< prev index next >

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

Print this page

        

*** 23,34 **** * questions. */ package jdk.tools.jmod; - import java.io.BufferedInputStream; - import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; --- 23,32 ----
*** 58,68 **** import java.nio.file.StandardCopyOption; import java.nio.file.attribute.BasicFileAttributes; import java.text.MessageFormat; import java.util.ArrayDeque; import java.util.ArrayList; - import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.Deque; import java.util.HashMap; --- 56,65 ----
*** 78,96 **** import java.util.function.Function; import java.util.function.Predicate; import java.util.function.Supplier; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.stream.Collectors; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; import java.util.zip.ZipEntry; import java.util.zip.ZipException; import java.util.zip.ZipFile; - import java.util.zip.ZipInputStream; - import java.util.zip.ZipOutputStream; import jdk.internal.joptsimple.BuiltinHelpFormatter; import jdk.internal.joptsimple.NonOptionArgumentSpec; import jdk.internal.joptsimple.OptionDescriptor; import jdk.internal.joptsimple.OptionException; import jdk.internal.joptsimple.OptionParser; --- 75,94 ---- import java.util.function.Function; import java.util.function.Predicate; import java.util.function.Supplier; import java.util.jar.JarEntry; import java.util.jar.JarFile; + import java.util.jar.JarOutputStream; import java.util.stream.Collectors; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; import java.util.zip.ZipEntry; import java.util.zip.ZipException; import java.util.zip.ZipFile; + import jdk.internal.jmod.JmodFile; + import jdk.internal.jmod.JmodFile.Section; import jdk.internal.joptsimple.BuiltinHelpFormatter; import jdk.internal.joptsimple.NonOptionArgumentSpec; import jdk.internal.joptsimple.OptionDescriptor; import jdk.internal.joptsimple.OptionException; import jdk.internal.joptsimple.OptionParser;
*** 248,274 **** private boolean hashModules() { return new Hasher(options.moduleFinder).run(); } private boolean describe() throws IOException { ! ZipFile zip = null; ! try { ! try { ! zip = new ZipFile(options.jmodFile.toFile()); ! } catch (IOException x) { ! throw new IOException("error opening jmod file", x); ! } ! ! try (InputStream in = Files.newInputStream(options.jmodFile)) { ! boolean found = printModuleDescriptor(in); ! if (!found) throw new CommandException("err.module.descriptor.not.found"); - return found; } - } finally { - if (zip != null) - zip.close(); } } static <T> String toString(Set<T> set) { if (set.isEmpty()) { return ""; } --- 246,263 ---- private boolean hashModules() { return new Hasher(options.moduleFinder).run(); } private boolean describe() throws IOException { ! try (JmodFile jf = new JmodFile(options.jmodFile)) { ! try (InputStream in = jf.getInputStream(Section.CLASSES, MODULE_INFO)) { ! ModuleDescriptor md = ModuleDescriptor.read(in); ! printModuleDescriptor(md); ! return true; ! } catch (IOException e) { throw new CommandException("err.module.descriptor.not.found"); } } } static <T> String toString(Set<T> set) { if (set.isEmpty()) { return ""; }
*** 276,296 **** .collect(joining(" ")); } private static final JavaLangModuleAccess JLMA = SharedSecrets.getJavaLangModuleAccess(); ! private boolean printModuleDescriptor(InputStream in) throws IOException { - final String mi = Section.CLASSES.jmodDir() + "/" + MODULE_INFO; - try (BufferedInputStream bis = new BufferedInputStream(in); - ZipInputStream zis = new ZipInputStream(bis)) { - - ZipEntry e; - while ((e = zis.getNextEntry()) != null) { - if (e.getName().equals(mi)) { - ModuleDescriptor md = ModuleDescriptor.read(zis); StringBuilder sb = new StringBuilder(); sb.append("\n").append(md.toNameAndVersion()); md.requires().stream() .sorted(Comparator.comparing(Requires::name)) --- 265,277 ---- .collect(joining(" ")); } private static final JavaLangModuleAccess JLMA = SharedSecrets.getJavaLangModuleAccess(); ! private void printModuleDescriptor(ModuleDescriptor md) throws IOException { StringBuilder sb = new StringBuilder(); sb.append("\n").append(md.toNameAndVersion()); md.requires().stream() .sorted(Comparator.comparing(Requires::name))
*** 330,357 **** mod -> sb.append("\n hashes ").append(mod).append(" ") .append(hashes.algorithm()).append(" ") .append(hashes.hashFor(mod)))); out.println(sb.toString()); - return true; - } - } - } - return false; } private boolean create() throws IOException { JmodFileWriter jmod = new JmodFileWriter(); // create jmod with temporary name to avoid it being examined // when scanning the module path Path target = options.jmodFile; Path tempTarget = target.resolveSibling(target.getFileName() + ".tmp"); try { ! try (OutputStream out = Files.newOutputStream(tempTarget); ! BufferedOutputStream bos = new BufferedOutputStream(out)) { ! jmod.write(bos); } Files.move(tempTarget, target); } catch (Exception e) { if (Files.exists(tempTarget)) { try { --- 311,332 ---- mod -> sb.append("\n hashes ").append(mod).append(" ") .append(hashes.algorithm()).append(" ") .append(hashes.hashFor(mod)))); out.println(sb.toString()); } private boolean create() throws IOException { JmodFileWriter jmod = new JmodFileWriter(); // create jmod with temporary name to avoid it being examined // when scanning the module path Path target = options.jmodFile; Path tempTarget = target.resolveSibling(target.getFileName() + ".tmp"); try { ! try (JmodOutputStream jos = JmodOutputStream.newOutputStream(tempTarget)) { ! jmod.write(jos); } Files.move(tempTarget, target); } catch (Exception e) { if (Files.exists(tempTarget)) { try {
*** 381,403 **** JmodFileWriter() { } /** * Writes the jmod to the given output stream. */ ! void write(OutputStream out) throws IOException { ! try (ZipOutputStream zos = new ZipOutputStream(out)) { ! // module-info.class ! writeModuleInfo(zos, findPackages(classpath)); // classes ! processClasses(zos, classpath); ! processSection(zos, Section.NATIVE_CMDS, cmds); ! processSection(zos, Section.NATIVE_LIBS, libs); ! processSection(zos, Section.CONFIG, configs); ! } } /** * Returns a supplier of an input stream to the module-info.class * on the class path of directories and JAR files. --- 356,375 ---- JmodFileWriter() { } /** * Writes the jmod to the given output stream. */ ! void write(JmodOutputStream out) throws IOException { // module-info.class ! writeModuleInfo(out, findPackages(classpath)); // classes ! processClasses(out, classpath); ! processSection(out, Section.NATIVE_CMDS, cmds); ! processSection(out, Section.NATIVE_LIBS, libs); ! processSection(out, Section.CONFIG, configs); } /** * Returns a supplier of an input stream to the module-info.class * on the class path of directories and JAR files.
*** 439,449 **** * * If --module-version, --main-class, or other options were provided * then the corresponding class file attributes are added to the * module-info here. */ ! void writeModuleInfo(ZipOutputStream zos, Set<String> packages) throws IOException { Supplier<InputStream> miSupplier = newModuleInfoSupplier(); if (miSupplier == null) { throw new IOException(MODULE_INFO + " not found"); --- 411,421 ---- * * If --module-version, --main-class, or other options were provided * then the corresponding class file attributes are added to the * module-info here. */ ! void writeModuleInfo(JmodOutputStream out, Set<String> packages) throws IOException { Supplier<InputStream> miSupplier = newModuleInfoSupplier(); if (miSupplier == null) { throw new IOException(MODULE_INFO + " not found");
*** 490,504 **** warning("warn.no.module.hashes", descriptor.name()); } } // write the (possibly extended or modified) module-info.class ! String e = Section.CLASSES.jmodDir() + "/" + MODULE_INFO; ! ZipEntry ze = new ZipEntry(e); ! zos.putNextEntry(ze); ! extender.write(zos); ! zos.closeEntry(); } } /* * Hasher resolves a module graph using the --hash-modules PATTERN --- 462,472 ---- warning("warn.no.module.hashes", descriptor.name()); } } // write the (possibly extended or modified) module-info.class ! out.writeEntry(extender.getBytes(), Section.CLASSES, MODULE_INFO); } } /* * Hasher resolves a module graph using the --hash-modules PATTERN
*** 625,635 **** return name.substring(0, index).replace('/', '.'); else return ""; } ! void processClasses(ZipOutputStream zos, List<Path> classpaths) throws IOException { if (classpaths == null) return; --- 593,603 ---- return name.substring(0, index).replace('/', '.'); else return ""; } ! void processClasses(JmodOutputStream zos, List<Path> classpaths) throws IOException { if (classpaths == null) return;
*** 643,667 **** } } } } ! void processSection(ZipOutputStream zos, Section section, List<Path> paths) throws IOException { if (paths == null) return; for (Path p : paths) processSection(zos, section, p); } ! void processSection(ZipOutputStream zos, Section section, Path top) throws IOException { - final String prefix = section.jmodDir(); - Files.walkFileTree(top, new SimpleFileVisitor<Path>() { @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { --- 611,633 ---- } } } } ! void processSection(JmodOutputStream zos, Section section, List<Path> paths) throws IOException { if (paths == null) return; for (Path p : paths) processSection(zos, section, p); } ! void processSection(JmodOutputStream out, Section section, Path top) throws IOException { Files.walkFileTree(top, new SimpleFileVisitor<Path>() { @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
*** 671,681 **** warning("warn.ignore.entry", MODULE_INFO, section); if (!relPath.toString().equals(MODULE_INFO) && !matches(relPath, excludes)) { try (InputStream in = Files.newInputStream(file)) { ! writeZipEntry(zos, in, prefix, relPath.toString()); } } return FileVisitResult.CONTINUE; } }); --- 637,653 ---- warning("warn.ignore.entry", MODULE_INFO, section); if (!relPath.toString().equals(MODULE_INFO) && !matches(relPath, excludes)) { try (InputStream in = Files.newInputStream(file)) { ! out.writeEntry(in, section, relPath.toString()); ! } catch (IOException x) { ! if (x.getMessage().contains("duplicate entry")) { ! warning("warn.ignore.duplicate.entry", relPath.toString(), section); ! return FileVisitResult.CONTINUE; ! } ! throw x; } } return FileVisitResult.CONTINUE; } });
*** 689,728 **** } } return false; } - void writeZipEntry(ZipOutputStream zos, InputStream in, String prefix, String other) - throws IOException - { - String name = Paths.get(prefix, other).toString() - .replace(File.separatorChar, '/'); - ZipEntry ze = new ZipEntry(name); - try { - zos.putNextEntry(ze); - in.transferTo(zos); - zos.closeEntry(); - } catch (ZipException x) { - if (x.getMessage().contains("duplicate entry")) { - warning("warn.ignore.duplicate.entry", name, prefix); - return; - } - throw x; - } - } - class JarEntryConsumer implements Consumer<JarEntry>, Predicate<JarEntry> { ! final ZipOutputStream zos; final JarFile jarfile; ! JarEntryConsumer(ZipOutputStream zos, JarFile jarfile) { ! this.zos = zos; this.jarfile = jarfile; } @Override public void accept(JarEntry je) { try (InputStream in = jarfile.getInputStream(je)) { ! writeZipEntry(zos, in, Section.CLASSES.jmodDir(), je.getName()); } catch (IOException e) { throw new UncheckedIOException(e); } } @Override --- 661,681 ---- } } return false; } class JarEntryConsumer implements Consumer<JarEntry>, Predicate<JarEntry> { ! final JmodOutputStream out; final JarFile jarfile; ! JarEntryConsumer(JmodOutputStream out, JarFile jarfile) { ! this.out = out; this.jarfile = jarfile; } @Override public void accept(JarEntry je) { try (InputStream in = jarfile.getInputStream(je)) { ! out.writeEntry(in, Section.CLASSES, je.getName()); } catch (IOException e) { throw new UncheckedIOException(e); } } @Override
*** 945,994 **** private void updateModuleInfo(String name, ModuleHashes moduleHashes) throws IOException { Path target = moduleNameToPath.get(name); Path tempTarget = target.resolveSibling(target.getFileName() + ".tmp"); - ZipFile zip = new ZipFile(target.toFile()); try { ! try (OutputStream out = Files.newOutputStream(tempTarget); ! ZipOutputStream zos = new ZipOutputStream(out)) { ! zip.stream().forEach(e -> { ! try { ! InputStream in = zip.getInputStream(e); ! if (e.getName().equals(MODULE_INFO) || ! e.getName().equals(Section.CLASSES.jmodDir() + "/" + MODULE_INFO)) { ! ZipEntry ze = new ZipEntry(e.getName()); ! ze.setTime(System.currentTimeMillis()); ! zos.putNextEntry(ze); ! recordHashes(in, zos, moduleHashes); ! zos.closeEntry(); } else { ! zos.putNextEntry(e); ! zos.write(in.readAllBytes()); ! zos.closeEntry(); ! } ! } catch (IOException x) { ! throw new UncheckedIOException(x); ! } ! }); } } catch (IOException|RuntimeException e) { if (Files.exists(tempTarget)) { try { Files.delete(tempTarget); } catch (IOException ioe) { e.addSuppressed(ioe); } } throw e; - } finally { - zip.close(); } out.println(getMessage("module.hashes.recorded", name)); Files.move(tempTarget, target, StandardCopyOption.REPLACE_EXISTING); } private Path moduleToPath(String name) { ModuleReference mref = moduleFinder.find(name).orElseThrow( () -> new InternalError("Selected module " + name + " not on module path")); URI uri = mref.location().get(); --- 898,983 ---- private void updateModuleInfo(String name, ModuleHashes moduleHashes) throws IOException { Path target = moduleNameToPath.get(name); Path tempTarget = target.resolveSibling(target.getFileName() + ".tmp"); try { ! if (target.getFileName().toString().endsWith(".jmod")) { ! updateJmodFile(target, tempTarget, moduleHashes); } else { ! updateModularJar(target, tempTarget, moduleHashes); } } catch (IOException|RuntimeException e) { if (Files.exists(tempTarget)) { try { Files.delete(tempTarget); } catch (IOException ioe) { e.addSuppressed(ioe); } } throw e; } + out.println(getMessage("module.hashes.recorded", name)); Files.move(tempTarget, target, StandardCopyOption.REPLACE_EXISTING); } + private void updateModularJar(Path target, Path tempTarget, + ModuleHashes moduleHashes) + throws IOException + { + try (JarFile jf = new JarFile(target.toFile()); + OutputStream out = Files.newOutputStream(tempTarget); + JarOutputStream jos = new JarOutputStream(out)) + { + jf.stream().forEach(e -> { + try (InputStream in = jf.getInputStream(e)) { + if (e.getName().equals(MODULE_INFO)) { + // what about module-info.class in versioned entries? + ZipEntry ze = new ZipEntry(e.getName()); + ze.setTime(System.currentTimeMillis()); + jos.putNextEntry(ze); + recordHashes(in, jos, moduleHashes); + jos.closeEntry(); + } else { + jos.putNextEntry(e); + jos.write(in.readAllBytes()); + jos.closeEntry(); + } + } catch (IOException x) { + throw new UncheckedIOException(x); + } + }); + } + } + + private void updateJmodFile(Path target, Path tempTarget, + ModuleHashes moduleHashes) + throws IOException + { + + try (JmodFile jf = new JmodFile(target); + JmodOutputStream jos = JmodOutputStream.newOutputStream(tempTarget)) + { + jf.stream().forEach(e -> { + try (InputStream in = jf.getInputStream(e.section(), e.name())) { + if (e.name().equals(MODULE_INFO)) { + // replace module-info.class + ModuleInfoExtender extender = + ModuleInfoExtender.newExtender(in); + extender.hashes(moduleHashes); + jos.writeEntry(extender.getBytes(), e.section(), e.name()); + } else { + jos.writeEntry(in, e); + } + } catch (IOException x) { + throw new UncheckedIOException(x); + } + }); + } + } + private Path moduleToPath(String name) { ModuleReference mref = moduleFinder.find(name).orElseThrow( () -> new InternalError("Selected module " + name + " not on module path")); URI uri = mref.location().get();
*** 999,1024 **** } return path; } } - enum Section { - NATIVE_LIBS("native"), - NATIVE_CMDS("bin"), - CLASSES("classes"), - CONFIG("conf"), - UNKNOWN("unknown"); - - private final String jmodDir; - - Section(String jmodDir) { - this.jmodDir = jmodDir; - } - - String jmodDir() { return jmodDir; } - } - static class ClassPathConverter implements ValueConverter<Path> { static final ValueConverter<Path> INSTANCE = new ClassPathConverter(); private static final Path CWD = Paths.get(""); --- 988,997 ----
< prev index next >