OpenJDK / jigsaw / jake / jdk
changeset 14169:521434b30dce
Add option that prints module descriptor to jmod, and various options cleanup
author | chegar |
---|---|
date | Thu, 01 Oct 2015 14:42:10 +0100 |
parents | 2b6cb5de27d5 |
children | 7187c680d9d0 |
files | src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java src/jdk.jlink/share/classes/jdk/tools/jmod/resources/jmod.properties test/jdk/jigsaw/launcher/basic/BasicTest.java test/jdk/jigsaw/module/ModuleReader/ModuleReaderTest.java test/jdk/jigsaw/tools/jmod/JmodNegativeTest.java test/jdk/jigsaw/tools/jmod/JmodTest.java |
diffstat | 6 files changed, 280 insertions(+), 92 deletions(-) [+] |
line wrap: on
line diff
--- a/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java Thu Oct 01 14:40:45 2015 +0100 +++ b/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java Thu Oct 01 14:42:10 2015 +0100 @@ -25,9 +25,11 @@ package jdk.tools.jmod; +import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; +import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -40,6 +42,7 @@ import java.lang.module.ModuleDescriptor; import java.lang.module.ModuleDescriptor.Version; import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.net.URI; import java.nio.file.FileSystems; import java.nio.file.FileVisitResult; @@ -76,6 +79,7 @@ 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; @@ -92,6 +96,8 @@ import jdk.internal.module.Hasher.DependencyHashes; import jdk.internal.module.ModuleInfoExtender; +import static java.util.stream.Collectors.joining; + /** * Implementation for the jmod tool. */ @@ -150,13 +156,14 @@ EXIT_SYSERR = 3, // System error or resource exhaustion. EXIT_ABNORMAL = 4;// terminated abnormally - enum Task { + enum Mode { CREATE, - LIST + LIST, + PRINT_DESCRIPTOR }; static class Options { - Task task; + Mode mode; Path jmodFile; boolean help; boolean version; @@ -189,15 +196,18 @@ } boolean ok; - switch (options.task) { + switch (options.mode) { case CREATE: ok = create(); break; case LIST: ok = list(); break; + case PRINT_DESCRIPTOR: + ok = printModuleDescriptor(); + break; default: - throw new AssertionError("Unknown task: " + options.task.name()); + throw new AssertionError("Unknown mode: " + options.mode.name()); } return ok ? EXIT_OK : EXIT_ERROR; @@ -274,6 +284,114 @@ return modPaths; } + private boolean printModuleDescriptor() 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 (FileInputStream fis = new FileInputStream(options.jmodFile.toFile())) { + boolean found = printModuleDescriptor(fis); + 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, + CharSequence prefix, + CharSequence suffix ) { + if (set.isEmpty()) { return ""; } + return set.stream().map(e -> e.toString()) + .collect(joining(", ", prefix, suffix)); + } + + private boolean printModuleDescriptor(FileInputStream fis) + throws IOException + { + final String mi = Section.CLASSES.jmodDir() + "/" + MODULE_INFO; + try (BufferedInputStream bis = new BufferedInputStream(fis); + 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("\nName:\n " + md.toNameAndVersion()); + + Set<Requires> requires = md.requires(); + if (!requires.isEmpty()) { + sb.append("\nRequires:"); + requires.forEach(r -> + sb.append("\n ").append(r.name()) + .append(toString(r.modifiers(), " [ ", " ]"))); + } + + Set<String> s = md.uses(); + if (!s.isEmpty()) { + sb.append("\nUses: "); + s.forEach(sv -> sb.append("\n ").append(sv)); + } + + Set<ModuleDescriptor.Exports> exports = md.exports(); + if (!exports.isEmpty()) { + sb.append("\nExports:"); + exports.forEach(sv -> sb.append("\n ").append(sv)); + } + + Map<String, ModuleDescriptor.Provides> provides = md.provides(); + if (!provides.isEmpty()) { + sb.append("\nProvides: "); + provides.values().forEach(p -> + sb.append("\n ").append(p.service()) + .append(" with ") + .append(toString(p.providers(), "", ""))); + } + + Optional<String> mc = md.mainClass(); + if (mc.isPresent()) + sb.append("\nMain class:\n " + mc.get()); + + s = md.conceals(); + if (!s.isEmpty()) { + sb.append("\nConceals:"); + s.forEach(p -> sb.append("\n ").append(p)); + } + + try { + Method m = ModuleDescriptor.class.getDeclaredMethod("hashes"); + m.setAccessible(true); + @SuppressWarnings("unchecked") + Optional<Hasher.DependencyHashes> optHashes = + (Optional<Hasher.DependencyHashes>) m.invoke(md); + + if (optHashes.isPresent()) { + Hasher.DependencyHashes hashes = optHashes.get(); + sb.append("\nHashes:"); + sb.append("\n Algorithm: " + hashes.algorithm()); + hashes.names().stream().forEach(mod -> + sb.append("\n ").append(mod) + .append(": ").append(hashes.hashFor(mod))); + } + } catch (ReflectiveOperationException x) { + throw new InternalError(x); + } + out.print(sb.toString()); + return true; + } + } + } + return false; + } + private boolean create() throws IOException { JmodFileWriter jmod = new JmodFileWriter(); @@ -768,16 +886,32 @@ String content = super.format(all); String[] lines = content.split("\n"); StringBuilder builder = new StringBuilder(); + + String modes = ".*--create.*|.*--list.*|.*--print-module-descriptor.*"; + boolean first = true; + for (String line : lines) { + if (line.matches(modes)) { + if (first) { + builder.append("\n").append(" Main operation modes:\n"); + first = false; + } + builder.append(" ").append(line).append("\n"); + } + } + builder.append("\n"); + String cmdfile = null; for (String line : lines) { if (line.startsWith("--@")) { cmdfile = line.replace("--" + CMD_FILENAME, CMD_FILENAME + " "); - } else { - builder.append(line).append("\n"); + } else if (line.startsWith("Option") || line.startsWith("------")) { + builder.append(" ").append(line).append("\n"); + } else if (!line.matches(modes)){ + builder.append(" ").append(line).append("\n"); } } if (cmdfile != null) { - builder.append(cmdfile).append("\n"); + builder.append(" ").append(cmdfile).append("\n"); } return builder.toString(); } @@ -788,6 +922,21 @@ private void handleOptions(String[] args) { parser.formatHelpWith(new JmodHelpFormatter()); + // Main operation modes + OptionSpec<Void> create + = parser.acceptsAll(Arrays.asList("c", "create"), + getMessage("main.opt.mode.create")); + + OptionSpec<Void> list + = parser.acceptsAll(Arrays.asList("t", "list"), + getMessage("main.opt.mode.list")); + + OptionSpec<Void> printDescriptor + = parser.acceptsAll(Arrays.asList("p", "print-module-descriptor"), + getMessage("main.opt.mode.pmd")); + + // options + OptionSpec<Path> classPath = parser.accepts("class-path", getMessage("main.opt.class-path")) .withRequiredArg() @@ -847,17 +996,38 @@ = parser.accepts("version", getMessage("main.opt.version")); NonOptionArgumentSpec<String> nonOptions - = parser.nonOptions(getMessage("main.non.opt.args")); + = parser.nonOptions(); try { OptionSet opts = parser.parse(args); - if (opts.specs().isEmpty() && opts.valuesOf(nonOptions).isEmpty()) - return; // usage summary will be shown + if (opts.has(help) || opts.has(version)) { + options = new Options(); + options.help = opts.has(help); + options.version = opts.has(version); + return; // informational message will be shown + } + + if (opts.specs().isEmpty() || + !(opts.has(create) || opts.has(list) || opts.has(printDescriptor))) + throw new CommandException("err.bad.main.mode").showUsage(true); options = new Options(); - options.help = opts.has(help); - options.version = opts.has(version); + + if (opts.has(create)) { + if (opts.has(list) || opts.has(printDescriptor)) + throw new CommandException("err.multiple.main.modes").showUsage(true); + options.mode = Mode.CREATE; + } else if (opts.has(list)) { + if (opts.has(create) || opts.has(printDescriptor)) + throw new CommandException("err.multiple.main.modes").showUsage(true); + options.mode = Mode.LIST; + } else if (opts.has(printDescriptor)) { + if (opts.has(create) || opts.has(list)) + throw new CommandException("err.multiple.main.modes").showUsage(true); + options.mode = Mode.PRINT_DESCRIPTOR; + } + if (opts.has(classPath)) options.classpath = opts.valuesOf(classPath); if (opts.has(cmds)) @@ -885,34 +1055,23 @@ throw new CommandException("err.modulepath.must.be.specified").showUsage(true); } - if (options.help || options.version) - return; // informational message will be shown - List<String> words = opts.valuesOf(nonOptions); if (words.isEmpty()) - throw new CommandException("err.missing.task").showUsage(true); - - String verb = words.get(0); - try { - options.task = Enum.valueOf(Task.class, verb.toUpperCase()); - } catch (IllegalArgumentException e) { - throw new CommandException("err.invalid.task", verb).showUsage(true); - } - - if (words.size() == 1) throw new CommandException("err.jmod.must.be.specified").showUsage(true); - Path path = Paths.get(words.get(1)); - if (options.task.equals(Task.CREATE) && Files.exists(path)) + Path path = Paths.get(words.get(0)); + if (options.mode.equals(Mode.CREATE) && Files.exists(path)) throw new CommandException("err.file.already.exists", path); - else if (options.task.equals(Task.LIST) && Files.notExists(path)) + else if ((options.mode.equals(Mode.LIST) || + options.mode.equals(Mode.PRINT_DESCRIPTOR)) + && Files.notExists(path)) throw new CommandException("err.jmod.not.found", path); options.jmodFile = path; - if (words.size() > 2) + if (words.size() > 1) throw new CommandException("err.unknown.option", - words.subList(2, words.size())).showUsage(true); + words.subList(1, words.size())).showUsage(true); - if (options.task.equals(Task.CREATE) && options.classpath == null) + if (options.mode.equals(Mode.CREATE) && options.classpath == null) throw new CommandException("err.classpath.must.be.specified").showUsage(true); if (options.mainClass != null && !isValidJavaIdentifier(options.mainClass)) throw new CommandException("err.invalid.main-class", options.mainClass);
--- a/src/jdk.jlink/share/classes/jdk/tools/jmod/resources/jmod.properties Thu Oct 01 14:40:45 2015 +0100 +++ b/src/jdk.jlink/share/classes/jdk/tools/jmod/resources/jmod.properties Thu Oct 01 14:42:10 2015 +0100 @@ -1,17 +1,16 @@ main.usage.summary=\ -Usage: {0} <create|list> <options> jmod-file\n\ +Usage: {0} [OPTIONS] jmod-file\n\ use --help for a list of possible options main.usage=\ -Usage: {0} <create|list> <options> jmod-file +Usage: {0} [OPTIONS] jmod-file error.prefix=Error: warn.prefix=Warning: -main.non.opt.args=\ -\create - Creates a new jmod archive\n\ -\list - Prints the names of all the entries in the jmod\n\ -\jmod-file - The jmod archive to operate on +main.opt.mode.create=Creates a new jmod archive +main.opt.mode.list=Prints the names of all the entries +main.opt.mode.pmd=Prints the module descriptor main.opt.help=Print this usage message main.opt.version=Version information @@ -27,10 +26,10 @@ main.opt.hash-dependencies=Compute and record hashes of dependencies matched by the pattern main.opt.cmdfile=Read options from the specified file +err.bad.main.mode=One of options -ctp must be specified. +err.multiple.main.modes=You may not specify more than one of '-ctp' option err.classpath.must.be.specified=--class-path must be specified err.jmod.must.be.specified=jmod-file must be specified -err.missing.task=one of create or list must be specified -err.invalid.task=task must be create|list: {0} err.invalid.version=invalid module version {0} err.output.must.be.specified:--output must be specified err.mods.must.be.specified:--mods must be specified @@ -50,4 +49,5 @@ err.internal.error=internal error: {0} {1} {2} err.invalid.arg.for.option=invalid argument for option: {0} err.option.after.class=option must be specified before classes: {0} +err.module.descriptor.not.found=Module descriptor not found warn.invalid.arg=Invalid classname or pathname not exist: {0}
--- a/test/jdk/jigsaw/launcher/basic/BasicTest.java Thu Oct 01 14:40:45 2015 +0100 +++ b/test/jdk/jigsaw/launcher/basic/BasicTest.java Thu Oct 01 14:42:10 2015 +0100 @@ -133,7 +133,7 @@ String cp = MODS_DIR.resolve(TEST_MODULE).toString(); String jmod = dir.resolve("m.jmod").toString(); String[] args = { - "create", + "--create", "--class-path", cp, "--main-class", MAIN_CLASS, jmod
--- a/test/jdk/jigsaw/module/ModuleReader/ModuleReaderTest.java Thu Oct 01 14:40:45 2015 +0100 +++ b/test/jdk/jigsaw/module/ModuleReader/ModuleReaderTest.java Thu Oct 01 14:42:10 2015 +0100 @@ -115,10 +115,10 @@ public void testJMod() throws Exception { Path dir = Files.createTempDirectory(USER_DIR, "mlib"); - // jmod create --class-path mods/${TESTMODULE} mlib/${TESTMODULE}.jmod + // jmod --create --class-path mods/${TESTMODULE} mlib/${TESTMODULE}.jmod String cp = MODS_DIR.resolve(TEST_MODULE).toString(); String jmod = dir.resolve("m.jmod").toString(); - String[] args = { "create", "--class-path", cp, jmod }; + String[] args = { "--create", "--class-path", cp, jmod }; jdk.tools.jmod.JmodTask task = new jdk.tools.jmod.JmodTask(); assertEquals(task.run(args), 0);
--- a/test/jdk/jigsaw/tools/jmod/JmodNegativeTest.java Thu Oct 01 14:40:45 2015 +0100 +++ b/test/jdk/jigsaw/tools/jmod/JmodNegativeTest.java Thu Oct 01 14:42:10 2015 +0100 @@ -75,7 +75,7 @@ jmod("") .assertFailure() .resultChecker(r -> - assertContains(r.output, "Error: task must be create|list:") + assertContains(r.output, "Error: One of options -ctp must be specified.") ); } @@ -84,7 +84,7 @@ jmod("badAction") .assertFailure() .resultChecker(r -> - assertContains(r.output, "Error: task must be create|list:") + assertContains(r.output, "Error: One of options -ctp must be specified.") ); jmod("--badOption") @@ -99,7 +99,7 @@ Path jmod = MODS_DIR.resolve("doesNotExist.jmod"); FileUtils.deleteFileIfExistsWithRetry(jmod); - jmod("create", + jmod("--create", jmod.toString(), "AAA") .assertFailure() @@ -110,7 +110,7 @@ @Test public void testCreateNoArgs() { - jmod("create") + jmod("--create") .assertFailure() .resultChecker(r -> assertContains(r.output, "Error: jmod-file must be specified") @@ -119,7 +119,7 @@ @Test public void testListNoArgs() { - jmod("list") + jmod("--list") .assertFailure() .resultChecker(r -> assertContains(r.output, "Error: jmod-file must be specified") @@ -131,7 +131,7 @@ Path jmod = MODS_DIR.resolve("doesNotExist.jmod"); FileUtils.deleteFileIfExistsWithRetry(jmod); - jmod("list", + jmod("--list", jmod.toString()) .assertFailure() .resultChecker(r -> @@ -146,7 +146,7 @@ if (Files.notExists(jmod)) Files.createDirectory(jmod); - jmod("list", + jmod("--list", jmod.toString()) .assertFailure() .resultChecker(r -> @@ -160,7 +160,7 @@ if (Files.notExists(jmod)) Files.createFile(jmod); - jmod("list", + jmod("--list", jmod.toString()) .assertFailure() .resultChecker(r -> @@ -170,7 +170,7 @@ @Test public void testHashDependenciesModulePathNotSpecified() { - jmod("create", + jmod("--create", "--hash-dependencies", "anyPattern.*", "output.jmod") .assertFailure() @@ -186,7 +186,7 @@ if (Files.notExists(jmod)) Files.createFile(jmod); - jmod("create", + jmod("--create", "--class-path", Paths.get(".").toString(), // anything that exists jmod.toString()) .assertFailure() @@ -201,7 +201,7 @@ if (Files.notExists(jmod)) Files.createDirectory(jmod); - jmod("create", + jmod("--create", "--class-path", Paths.get(".").toString(), // anything that exists jmod.toString()) .assertFailure() @@ -217,7 +217,7 @@ String cp = EXPLODED_DIR.resolve("foo").resolve("classes").toString(); for (String version : new String[] { "", "NOT_A_VALID_VERSION" }) { - jmod("create", + jmod("--create", "--class-path", cp, "--module-version", version, jmod.toString()) @@ -234,7 +234,7 @@ FileUtils.deleteFileIfExistsWithRetry(jmod); String cp = EXPLODED_DIR.resolve("foo").resolve("classes").toString(); - jmod("create", + jmod("--create", "--class-path", cp + pathSeparator + cp, jmod.toString()) .assertFailure() @@ -251,7 +251,7 @@ FileUtils.deleteFileIfExistsWithRetry(jar); Files.createFile(jar); - jmod("create", + jmod("--create", "--class-path", jar.toString(), jmod.toString()) .assertFailure() @@ -271,7 +271,7 @@ // empty } - jmod("create", + jmod("--create", "--class-path", jar.toString(), jmod.toString()) .assertFailure() @@ -288,7 +288,7 @@ FileUtils.deleteFileIfExistsWithRetry(jar); Files.createDirectory(jar); - jmod("create", + jmod("--create", "--class-path", jar.toString(), jmod.toString()) .assertFailure() @@ -306,7 +306,7 @@ Files.createDirectory(cp); Files.createFile(cp.resolve("nada.txt")); - jmod("create", + jmod("--create", "--class-path", cp.toString(), jmod.toString()) .assertFailure() @@ -325,7 +325,7 @@ Files.createDirectory(emptyDir); String cp = EXPLODED_DIR.resolve("foo").resolve("classes").toString(); - jmod("create", + jmod("--create", "--class-path", cp, "--hash-dependencies", ".*", "--modulepath", emptyDir.toString(), @@ -347,7 +347,7 @@ try { String cp = EXPLODED_DIR.resolve("foo").resolve("classes").toString(); - jmod("create", + jmod("--create", "--class-path", cp, "--hash-dependencies", ".*", "--modulepath", MODS_DIR.toString(), @@ -369,7 +369,7 @@ FileUtils.deleteFileIfExistsWithRetry(file); Files.createFile(file); - jmod("create", + jmod("--create", "--hash-dependencies", ".*", "--modulepath", file.toString(), jmod.toString()) @@ -386,23 +386,23 @@ FileUtils.deleteFileIfExistsWithRetry(Paths.get("doesNotExist")); List<Supplier<JmodResult>> tasks = Arrays.asList( - () -> jmod("create", + () -> jmod("--create", "--hash-dependencies", "anyPattern", "--modulepath", "doesNotExist", "output.jmod"), - () -> jmod("create", + () -> jmod("--create", "--class-path", "doesNotExist", "output.jmod"), - () -> jmod("create", + () -> jmod("--create", "--class-path", "doesNotExist.jar", "output.jmod"), - () -> jmod("create", + () -> jmod("--create", "--cmds", "doesNotExist", "output.jmod"), - () -> jmod("create", + () -> jmod("--create", "--config", "doesNotExist", "output.jmod"), - () -> jmod("create", + () -> jmod("--create", "--libs", "doesNotExist", "output.jmod") ); @@ -434,23 +434,23 @@ Files.createDirectory(emptyDir); List<Supplier<JmodResult>> tasks = Arrays.asList( - () -> jmod("create", + () -> jmod("--create", "--hash-dependencies", "anyPattern", "--modulepath","empty" + pathSeparator + "doesNotExist", "output.jmod"), - () -> jmod("create", + () -> jmod("--create", "--class-path", "empty" + pathSeparator + "doesNotExist", "output.jmod"), - () -> jmod("create", + () -> jmod("--create", "--class-path", "empty" + pathSeparator + "doesNotExist.jar", "output.jmod"), - () -> jmod("create", + () -> jmod("--create", "--cmds", "empty" + pathSeparator + "doesNotExist", "output.jmod"), - () -> jmod("create", + () -> jmod("--create", "--config", "empty" + pathSeparator + "doesNotExist", "output.jmod"), - () -> jmod("create", + () -> jmod("--create", "--libs", "empty" + pathSeparator + "doesNotExist", "output.jmod") ); @@ -481,19 +481,19 @@ Files.createFile(aFile); List<Supplier<JmodResult>> tasks = Arrays.asList( - () -> jmod("create", + () -> jmod("--create", "--class-path", "aFile.txt", "output.jmod"), - () -> jmod("create", + () -> jmod("--create", "--modulepath", "aFile.txt", "output.jmod"), - () -> jmod("create", + () -> jmod("--create", "--cmds", "aFile.txt", "output.jmod"), - () -> jmod("create", + () -> jmod("--create", "--config", "aFile.txt", "output.jmod"), - () -> jmod("create", + () -> jmod("--create", "--libs", "aFile.txt", "output.jmod") );
--- a/test/jdk/jigsaw/tools/jmod/JmodTest.java Thu Oct 01 14:40:45 2015 +0100 +++ b/test/jdk/jigsaw/tools/jmod/JmodTest.java Thu Oct 01 14:42:10 2015 +0100 @@ -36,6 +36,7 @@ import java.nio.file.*; import java.util.*; import java.util.function.Consumer; +import java.util.regex.Pattern; import java.util.stream.Stream; import jdk.testlibrary.FileUtils; import org.testng.annotations.BeforeTest; @@ -78,12 +79,12 @@ @Test public void testList() throws IOException { String cp = EXPLODED_DIR.resolve("foo").resolve("classes").toString(); - jmod("create", + jmod("--create", "--class-path", cp, MODS_DIR.resolve("foo.jmod").toString()) .assertSuccess(); - jmod("list", + jmod("--list", MODS_DIR.resolve("foo.jmod").toString()) .assertSuccess() .resultChecker(r -> { @@ -100,7 +101,7 @@ FileUtils.deleteFileIfExistsWithRetry(jmod); String cp = EXPLODED_DIR.resolve("foo").resolve("classes").toString(); - jmod("create", + jmod("--create", "--class-path", cp, "--main-class", "jdk.test.foo.Foo", jmod.toString()) @@ -118,7 +119,7 @@ FileUtils.deleteFileIfExistsWithRetry(jmod); String cp = EXPLODED_DIR.resolve("foo").resolve("classes").toString(); - jmod("create", + jmod("--create", "--class-path", cp, "--module-version", "5.4.3", jmod.toString()) @@ -137,7 +138,7 @@ Path cp = EXPLODED_DIR.resolve("foo").resolve("classes"); Path cf = EXPLODED_DIR.resolve("foo").resolve("conf"); - jmod("create", + jmod("--create", "--class-path", cp.toString(), "--config", cf.toString(), jmod.toString()) @@ -159,7 +160,7 @@ Path cp = EXPLODED_DIR.resolve("foo").resolve("classes"); Path bp = EXPLODED_DIR.resolve("foo").resolve("bin"); - jmod("create", + jmod("--create", "--cmds", bp.toString(), "--class-path", cp.toString(), jmod.toString()) @@ -181,7 +182,7 @@ Path cp = EXPLODED_DIR.resolve("foo").resolve("classes"); Path lp = EXPLODED_DIR.resolve("foo").resolve("lib"); - jmod("create", + jmod("--create", "--libs=", lp.toString(), "--class-path", cp.toString(), jmod.toString()) @@ -205,7 +206,7 @@ Path lp = EXPLODED_DIR.resolve("foo").resolve("lib"); Path cf = EXPLODED_DIR.resolve("foo").resolve("conf"); - jmod("create", + jmod("--create", "--conf", cf.toString(), "--cmds=", bp.toString(), "--libs=", lp.toString(), @@ -232,7 +233,7 @@ Path cp = EXPLODED_DIR.resolve("foo").resolve("classes"); Path lp = EXPLODED_DIR.resolve("foo").resolve("lib"); - jmod("create", + jmod("--create", "--libs=", lp.toString(), "--class-path", cp.toString(), "--exclude", "**internal**", @@ -255,6 +256,34 @@ } @Test + public void printModuleDescriptorFoo() throws IOException { + String cp = EXPLODED_DIR.resolve("foo").resolve("classes").toString(); + jmod("--create", + "--class-path", cp, + MODS_DIR.resolve("printModuleDescriptorFoo.jmod").toString()) + .assertSuccess(); + + for (String opt : new String[] {"--print-module-descriptor", "-p" }) { + jmod(opt, + MODS_DIR.resolve("printModuleDescriptorFoo.jmod").toString()) + .assertSuccess() + .resultChecker(r -> { + // Expect similar output: "Name:foo, Requires: java.base + // Exports: jdk.test.foo, Conceals: jdk.test.foo.internal" + Pattern p = Pattern.compile("\\s+Name:\\s+foo\\s+Requires:\\s+java.base"); + assertTrue(p.matcher(r.output).find(), + "Expecting to find \"Name: foo, Requires: java.base\"" + + "in output, but did not: [" + r.output + "]"); + p = Pattern.compile( + "Exports:\\s+jdk.test.foo\\s+Conceals:\\s+jdk.test.foo.internal"); + assertTrue(p.matcher(r.output).find(), + "Expecting to find \"Exports: ..., Conceals: ...\"" + + "in output, but did not: [" + r.output + "]"); + }); + } + } + + @Test public void testVersion() { jmod("--version") .assertSuccess() @@ -284,7 +313,7 @@ Files.createFile(tmp); String cp = EXPLODED_DIR.resolve("foo").resolve("classes").toString(); - jmod("create", + jmod("--create", "--class-path", cp, jmod.toString()) .assertSuccess() @@ -304,7 +333,7 @@ assertTrue(true); else assertTrue(false,"Expected to find [" + subString + "], in output [" - + output + "]"); + + output + "]" + "\n"); } static ModuleDescriptor getModuleDescriptor(Path jmod) { @@ -331,7 +360,7 @@ } static Set<String> getJmodContent(Path jmod) { - JmodResult r = jmod("list", jmod.toString()).assertSuccess(); + JmodResult r = jmod("--list", jmod.toString()).assertSuccess(); return Stream.of(r.output.split("\r?\n")).collect(toSet()); }