< 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 >