< prev index next >

src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java

Print this page




  56 import java.nio.file.Paths;
  57 import java.nio.file.SimpleFileVisitor;
  58 import java.nio.file.StandardCopyOption;
  59 import java.nio.file.attribute.BasicFileAttributes;
  60 import java.text.MessageFormat;
  61 import java.util.ArrayList;
  62 import java.util.Collection;
  63 import java.util.Collections;
  64 import java.util.Comparator;
  65 import java.util.HashSet;
  66 import java.util.LinkedHashMap;
  67 import java.util.List;
  68 import java.util.Locale;
  69 import java.util.Map;
  70 import java.util.MissingResourceException;
  71 import java.util.Optional;
  72 import java.util.ResourceBundle;
  73 import java.util.Set;
  74 import java.util.TreeSet;
  75 import java.util.function.Consumer;
  76 import java.util.function.Function;
  77 import java.util.function.Predicate;
  78 import java.util.function.Supplier;
  79 import java.util.jar.JarEntry;
  80 import java.util.jar.JarFile;
  81 import java.util.jar.JarOutputStream;
  82 import java.util.stream.Collectors;
  83 import java.util.regex.Pattern;
  84 import java.util.regex.PatternSyntaxException;
  85 import java.util.zip.ZipEntry;
  86 import java.util.zip.ZipException;
  87 import java.util.zip.ZipFile;
  88 
  89 import jdk.internal.jmod.JmodFile;
  90 import jdk.internal.jmod.JmodFile.Section;
  91 import jdk.internal.joptsimple.BuiltinHelpFormatter;
  92 import jdk.internal.joptsimple.NonOptionArgumentSpec;
  93 import jdk.internal.joptsimple.OptionDescriptor;
  94 import jdk.internal.joptsimple.OptionException;
  95 import jdk.internal.joptsimple.OptionParser;
  96 import jdk.internal.joptsimple.OptionSet;


 378                              .append(toHex(hashes.hashFor(mod))));
 379         }
 380 
 381         out.println(sb.toString());
 382     }
 383 
 384     private String toHex(byte[] ba) {
 385         StringBuilder sb = new StringBuilder(ba.length);
 386         for (byte b: ba) {
 387             sb.append(String.format("%02x", b & 0xff));
 388         }
 389         return sb.toString();
 390     }
 391 
 392     private boolean create() throws IOException {
 393         JmodFileWriter jmod = new JmodFileWriter();
 394 
 395         // create jmod with temporary name to avoid it being examined
 396         // when scanning the module path
 397         Path target = options.jmodFile;
 398         Path tempTarget = Files.createTempFile(target.getFileName().toString(), ".tmp");
 399         try {
 400             try (JmodOutputStream jos = JmodOutputStream.newOutputStream(tempTarget)) {
 401                 jmod.write(jos);
 402             }
 403             Files.move(tempTarget, target);

 404         } catch (Exception e) {
 405             if (Files.exists(tempTarget)) {



















 406                 try {
 407                     Files.delete(tempTarget);
 408                 } catch (IOException ioe) {
 409                     e.addSuppressed(ioe);
 410                 }






 411             }
 412             throw e;
 413         }
 414         return true;
 415     }
 416 
 417     private class JmodFileWriter {
 418         final List<Path> cmds = options.cmds;
 419         final List<Path> libs = options.libs;
 420         final List<Path> configs = options.configs;
 421         final List<Path> classpath = options.classpath;
 422         final List<Path> headerFiles = options.headerFiles;
 423         final List<Path> manPages = options.manPages;
 424         final List<Path> legalNotices = options.legalNotices;
 425 
 426         final Version moduleVersion = options.moduleVersion;
 427         final String mainClass = options.mainClass;
 428         final String osName = options.osName;
 429         final String osArch = options.osArch;
 430         final String osVersion = options.osVersion;
 431         final List<PathMatcher> excludes = options.excludes;
 432         final ModuleResolution moduleResolution = options.moduleResolution;
 433 
 434         JmodFileWriter() { }


 891         /**
 892          * Reads the given input stream of module-info.class and write
 893          * the extended module-info.class with the given ModuleHashes
 894          *
 895          * @param in       InputStream of module-info.class
 896          * @param out      OutputStream to write the extended module-info.class
 897          * @param hashes   ModuleHashes
 898          */
 899         private void recordHashes(InputStream in, OutputStream out, ModuleHashes hashes)
 900             throws IOException
 901         {
 902             ModuleInfoExtender extender = ModuleInfoExtender.newExtender(in);
 903             extender.hashes(hashes);
 904             extender.write(out);
 905         }
 906 
 907         void updateModuleInfo(String name, ModuleHashes moduleHashes)
 908             throws IOException
 909         {
 910             Path target = moduleToPath(name);
 911             Path tempTarget = Files.createTempFile(target.getFileName().toString(), ".tmp");
 912             try {
 913                 if (target.getFileName().toString().endsWith(".jmod")) {
 914                     updateJmodFile(target, tempTarget, moduleHashes);
 915                 } else {
 916                     updateModularJar(target, tempTarget, moduleHashes);
 917                 }
 918             } catch (IOException|RuntimeException e) {
 919                 if (Files.exists(tempTarget)) {
 920                     try {
 921                         Files.delete(tempTarget);
 922                     } catch (IOException ioe) {
 923                         e.addSuppressed(ioe);
 924                     }
 925                 }
 926                 throw e;
 927             }
 928 
 929             out.println(getMessage("module.hashes.recorded", name));
 930             Files.move(tempTarget, target, StandardCopyOption.REPLACE_EXISTING);

 931         }
 932 
 933         private void updateModularJar(Path target, Path tempTarget,
 934                                       ModuleHashes moduleHashes)
 935             throws IOException
 936         {
 937             try (JarFile jf = new JarFile(target.toFile());
 938                  OutputStream out = Files.newOutputStream(tempTarget);
 939                  JarOutputStream jos = new JarOutputStream(out))
 940             {
 941                 jf.stream().forEach(e -> {
 942                     try (InputStream in = jf.getInputStream(e)) {
 943                         if (e.getName().equals(MODULE_INFO)) {
 944                             // what about module-info.class in versioned entries?
 945                             ZipEntry ze = new ZipEntry(e.getName());
 946                             ze.setTime(System.currentTimeMillis());
 947                             jos.putNextEntry(ze);
 948                             recordHashes(in, jos, moduleHashes);
 949                             jos.closeEntry();
 950                         } else {




  56 import java.nio.file.Paths;
  57 import java.nio.file.SimpleFileVisitor;
  58 import java.nio.file.StandardCopyOption;
  59 import java.nio.file.attribute.BasicFileAttributes;
  60 import java.text.MessageFormat;
  61 import java.util.ArrayList;
  62 import java.util.Collection;
  63 import java.util.Collections;
  64 import java.util.Comparator;
  65 import java.util.HashSet;
  66 import java.util.LinkedHashMap;
  67 import java.util.List;
  68 import java.util.Locale;
  69 import java.util.Map;
  70 import java.util.MissingResourceException;
  71 import java.util.Optional;
  72 import java.util.ResourceBundle;
  73 import java.util.Set;
  74 import java.util.TreeSet;
  75 import java.util.function.Consumer;

  76 import java.util.function.Predicate;
  77 import java.util.function.Supplier;
  78 import java.util.jar.JarEntry;
  79 import java.util.jar.JarFile;
  80 import java.util.jar.JarOutputStream;
  81 import java.util.stream.Collectors;
  82 import java.util.regex.Pattern;
  83 import java.util.regex.PatternSyntaxException;
  84 import java.util.zip.ZipEntry;
  85 import java.util.zip.ZipException;
  86 import java.util.zip.ZipFile;
  87 
  88 import jdk.internal.jmod.JmodFile;
  89 import jdk.internal.jmod.JmodFile.Section;
  90 import jdk.internal.joptsimple.BuiltinHelpFormatter;
  91 import jdk.internal.joptsimple.NonOptionArgumentSpec;
  92 import jdk.internal.joptsimple.OptionDescriptor;
  93 import jdk.internal.joptsimple.OptionException;
  94 import jdk.internal.joptsimple.OptionParser;
  95 import jdk.internal.joptsimple.OptionSet;


 377                              .append(toHex(hashes.hashFor(mod))));
 378         }
 379 
 380         out.println(sb.toString());
 381     }
 382 
 383     private String toHex(byte[] ba) {
 384         StringBuilder sb = new StringBuilder(ba.length);
 385         for (byte b: ba) {
 386             sb.append(String.format("%02x", b & 0xff));
 387         }
 388         return sb.toString();
 389     }
 390 
 391     private boolean create() throws IOException {
 392         JmodFileWriter jmod = new JmodFileWriter();
 393 
 394         // create jmod with temporary name to avoid it being examined
 395         // when scanning the module path
 396         Path target = options.jmodFile;
 397         Path tempTarget = jmodTempFilePath(target);
 398         try {
 399             try (JmodOutputStream jos = JmodOutputStream.newOutputStream(tempTarget)) {
 400                 jmod.write(jos);
 401             }
 402             Files.move(tempTarget, target);
 403             Files.deleteIfExists(tempTarget.getParent());
 404         } catch (Exception e) {
 405             deleteTempFile(tempTarget, e);
 406             throw e;
 407         }
 408         return true;
 409     }
 410 
 411     /*
 412      * Create a JMOD .tmp file for the given target JMOD file in
 413      * a temporary directory
 414      */
 415     private static Path jmodTempFilePath(Path target) throws IOException {
 416         String fn = target.getFileName().toString();
 417         Path dir = Files.createTempDirectory(fn);
 418         return dir.resolve(fn + ".tmp");
 419     }
 420 
 421     /**
 422      * delete temporary directory and temporary jmod file
 423      */
 424     private static void deleteTempFile(Path tempTarget, Exception e) {
 425         try {
 426             Files.deleteIfExists(tempTarget);
 427         } catch (IOException ioe) {
 428             e.addSuppressed(ioe);
 429         }
 430 
 431         Path tmpdir = tempTarget.getParent();
 432         try {
 433             Files.deleteIfExists(tmpdir);
 434         } catch (IOException ioe) {
 435             e.addSuppressed(ioe);
 436         }



 437     }
 438 
 439     private class JmodFileWriter {
 440         final List<Path> cmds = options.cmds;
 441         final List<Path> libs = options.libs;
 442         final List<Path> configs = options.configs;
 443         final List<Path> classpath = options.classpath;
 444         final List<Path> headerFiles = options.headerFiles;
 445         final List<Path> manPages = options.manPages;
 446         final List<Path> legalNotices = options.legalNotices;
 447 
 448         final Version moduleVersion = options.moduleVersion;
 449         final String mainClass = options.mainClass;
 450         final String osName = options.osName;
 451         final String osArch = options.osArch;
 452         final String osVersion = options.osVersion;
 453         final List<PathMatcher> excludes = options.excludes;
 454         final ModuleResolution moduleResolution = options.moduleResolution;
 455 
 456         JmodFileWriter() { }


 913         /**
 914          * Reads the given input stream of module-info.class and write
 915          * the extended module-info.class with the given ModuleHashes
 916          *
 917          * @param in       InputStream of module-info.class
 918          * @param out      OutputStream to write the extended module-info.class
 919          * @param hashes   ModuleHashes
 920          */
 921         private void recordHashes(InputStream in, OutputStream out, ModuleHashes hashes)
 922             throws IOException
 923         {
 924             ModuleInfoExtender extender = ModuleInfoExtender.newExtender(in);
 925             extender.hashes(hashes);
 926             extender.write(out);
 927         }
 928 
 929         void updateModuleInfo(String name, ModuleHashes moduleHashes)
 930             throws IOException
 931         {
 932             Path target = moduleToPath(name);
 933             Path tempTarget = jmodTempFilePath(target);
 934             try {
 935                 if (target.getFileName().toString().endsWith(".jmod")) {
 936                     updateJmodFile(target, tempTarget, moduleHashes);
 937                 } else {
 938                     updateModularJar(target, tempTarget, moduleHashes);
 939                 }
 940             } catch (IOException|RuntimeException e) {
 941                 deleteTempFile(tempTarget, e);






 942                 throw e;
 943             }
 944 
 945             out.println(getMessage("module.hashes.recorded", name));
 946             Files.move(tempTarget, target, StandardCopyOption.REPLACE_EXISTING);
 947             Files.deleteIfExists(tempTarget.getParent());
 948         }
 949 
 950         private void updateModularJar(Path target, Path tempTarget,
 951                                       ModuleHashes moduleHashes)
 952             throws IOException
 953         {
 954             try (JarFile jf = new JarFile(target.toFile());
 955                  OutputStream out = Files.newOutputStream(tempTarget);
 956                  JarOutputStream jos = new JarOutputStream(out))
 957             {
 958                 jf.stream().forEach(e -> {
 959                     try (InputStream in = jf.getInputStream(e)) {
 960                         if (e.getName().equals(MODULE_INFO)) {
 961                             // what about module-info.class in versioned entries?
 962                             ZipEntry ze = new ZipEntry(e.getName());
 963                             ze.setTime(System.currentTimeMillis());
 964                             jos.putNextEntry(ze);
 965                             recordHashes(in, jos, moduleHashes);
 966                             jos.closeEntry();
 967                         } else {


< prev index next >