< prev index next >

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

Print this page




  87 import java.util.stream.Stream;
  88 import java.util.zip.ZipEntry;
  89 import java.util.zip.ZipException;
  90 import java.util.zip.ZipFile;
  91 
  92 import jdk.internal.jmod.JmodFile;
  93 import jdk.internal.jmod.JmodFile.Section;
  94 import jdk.internal.joptsimple.BuiltinHelpFormatter;
  95 import jdk.internal.joptsimple.NonOptionArgumentSpec;
  96 import jdk.internal.joptsimple.OptionDescriptor;
  97 import jdk.internal.joptsimple.OptionException;
  98 import jdk.internal.joptsimple.OptionParser;
  99 import jdk.internal.joptsimple.OptionSet;
 100 import jdk.internal.joptsimple.OptionSpec;
 101 import jdk.internal.joptsimple.ValueConverter;
 102 import jdk.internal.loader.ResourceHelper;
 103 import jdk.internal.misc.JavaLangModuleAccess;
 104 import jdk.internal.misc.SharedSecrets;
 105 import jdk.internal.module.ModuleHashes;
 106 import jdk.internal.module.ModuleInfoExtender;

 107 import jdk.tools.jlink.internal.Utils;
 108 
 109 import static java.util.stream.Collectors.joining;
 110 
 111 /**
 112  * Implementation for the jmod tool.
 113  */
 114 public class JmodTask {
 115 
 116     static class CommandException extends RuntimeException {
 117         private static final long serialVersionUID = 0L;
 118         boolean showUsage;
 119 
 120         CommandException(String key, Object... args) {
 121             super(getMessageOrKey(key, args));
 122         }
 123 
 124         CommandException showUsage(boolean b) {
 125             showUsage = b;
 126             return this;


 159     };
 160 
 161     static class Options {
 162         Mode mode;
 163         Path jmodFile;
 164         boolean help;
 165         boolean version;
 166         List<Path> classpath;
 167         List<Path> cmds;
 168         List<Path> configs;
 169         List<Path> libs;
 170         List<Path> headerFiles;
 171         List<Path> manPages;
 172         ModuleFinder moduleFinder;
 173         Version moduleVersion;
 174         String mainClass;
 175         String osName;
 176         String osArch;
 177         String osVersion;
 178         Pattern modulesToHash;


 179         boolean dryrun;
 180         List<PathMatcher> excludes;
 181     }
 182 
 183     public int run(String[] args) {
 184 
 185         try {
 186             handleOptions(args);
 187             if (options == null) {
 188                 showUsageSummary();
 189                 return EXIT_CMDERR;
 190             }
 191             if (options.help) {
 192                 showHelp();
 193                 return EXIT_OK;
 194             }
 195             if (options.version) {
 196                 showVersion();
 197                 return EXIT_OK;
 198             }


 307         md.provides().stream()
 308             .sorted(Comparator.comparing(Provides::service))
 309             .forEach(p -> sb.append("\n  provides ").append(p.service())
 310                             .append(" with ")
 311                             .append(toString(p.providers())));
 312 
 313         md.mainClass().ifPresent(v -> sb.append("\n  main-class " + v));
 314 
 315         md.osName().ifPresent(v -> sb.append("\n  operating-system-name " + v));
 316 
 317         md.osArch().ifPresent(v -> sb.append("\n  operating-system-architecture " + v));
 318 
 319         md.osVersion().ifPresent(v -> sb.append("\n  operating-system-version " + v));
 320 
 321         JLMA.hashes(md).ifPresent(
 322             hashes -> hashes.names().stream().sorted().forEach(
 323                 mod -> sb.append("\n  hashes ").append(mod).append(" ")
 324                          .append(hashes.algorithm()).append(" ")
 325                          .append(hashes.hashFor(mod))));
 326 







 327         out.println(sb.toString());
 328     }
 329 
 330     private boolean create() throws IOException {
 331         JmodFileWriter jmod = new JmodFileWriter();
 332 
 333         // create jmod with temporary name to avoid it being examined
 334         // when scanning the module path
 335         Path target = options.jmodFile;
 336         Path tempTarget = target.resolveSibling(target.getFileName() + ".tmp");
 337         try {
 338             try (JmodOutputStream jos = JmodOutputStream.newOutputStream(tempTarget)) {
 339                 jmod.write(jos);
 340             }
 341             Files.move(tempTarget, target);
 342         } catch (Exception e) {
 343             if (Files.exists(tempTarget)) {
 344                 try {
 345                     Files.delete(tempTarget);
 346                 } catch (IOException ioe) {


 350             throw e;
 351         }
 352         return true;
 353     }
 354 
 355     private class JmodFileWriter {
 356         final List<Path> cmds = options.cmds;
 357         final List<Path> libs = options.libs;
 358         final List<Path> configs = options.configs;
 359         final List<Path> classpath = options.classpath;
 360         final List<Path> headerFiles = options.headerFiles;
 361         final List<Path> manPages = options.manPages;
 362 
 363         final Version moduleVersion = options.moduleVersion;
 364         final String mainClass = options.mainClass;
 365         final String osName = options.osName;
 366         final String osArch = options.osArch;
 367         final String osVersion = options.osVersion;
 368         final List<PathMatcher> excludes = options.excludes;
 369         final Hasher hasher = hasher();


 370 
 371         JmodFileWriter() { }
 372 
 373         /**
 374          * Writes the jmod to the given output stream.
 375          */
 376         void write(JmodOutputStream out) throws IOException {
 377             // module-info.class
 378             writeModuleInfo(out, findPackages(classpath));
 379 
 380             // classes
 381             processClasses(out, classpath);
 382 
 383             processSection(out, Section.NATIVE_CMDS, cmds);
 384             processSection(out, Section.NATIVE_LIBS, libs);
 385             processSection(out, Section.CONFIG, configs);
 386             processSection(out, Section.HEADER_FILES, headerFiles);
 387             processSection(out, Section.MAN_PAGES, manPages);
 388 
 389         }


 458                 if (mainClass != null)
 459                     extender.mainClass(mainClass);
 460 
 461                 // --os-name, --os-arch, --os-version
 462                 if (osName != null || osArch != null || osVersion != null)
 463                     extender.targetPlatform(osName, osArch, osVersion);
 464 
 465                 // --module-version
 466                 if (moduleVersion != null)
 467                     extender.version(moduleVersion);
 468 
 469                 if (hasher != null) {
 470                     ModuleHashes moduleHashes = hasher.computeHashes(descriptor.name());
 471                     if (moduleHashes != null) {
 472                         extender.hashes(moduleHashes);
 473                     } else {
 474                         warning("warn.no.module.hashes", descriptor.name());
 475                     }
 476                 }
 477 



 478                 // write the (possibly extended or modified) module-info.class
 479                 out.writeEntry(extender.toByteArray(), Section.CLASSES, MODULE_INFO);
 480             }
 481         }
 482 
 483         /*
 484          * Hasher resolves a module graph using the --hash-modules PATTERN
 485          * as the roots.
 486          *
 487          * The jmod file is being created and does not exist in the
 488          * given modulepath.
 489          */
 490         private Hasher hasher() {
 491             if (options.modulesToHash == null)
 492                 return null;
 493 
 494             try {
 495                 Supplier<InputStream> miSupplier = newModuleInfoSupplier();
 496                 if (miSupplier == null) {
 497                     throw new IOException(MODULE_INFO + " not found");


1082 
1083     static class PatternConverter implements ValueConverter<Pattern> {
1084         @Override
1085         public Pattern convert(String value) {
1086             try {
1087                 if (value.startsWith("regex:")) {
1088                     value = value.substring("regex:".length()).trim();
1089                 }
1090 
1091                 return Pattern.compile(value);
1092             } catch (PatternSyntaxException e) {
1093                 throw new CommandException("err.bad.pattern", value);
1094             }
1095         }
1096 
1097         @Override public Class<Pattern> valueType() { return Pattern.class; }
1098 
1099         @Override public String valuePattern() { return "regex-pattern"; }
1100     }
1101 






















1102     static class PathMatcherConverter implements ValueConverter<PathMatcher> {
1103         @Override
1104         public PathMatcher convert(String pattern) {
1105             try {
1106                 return Utils.getPathMatcher(FileSystems.getDefault(), pattern);
1107             } catch (PatternSyntaxException e) {
1108                 throw new CommandException("err.bad.pattern", pattern);
1109             }
1110         }
1111 
1112         @Override public Class<PathMatcher> valueType() { return PathMatcher.class; }
1113 
1114         @Override public String valuePattern() { return "pattern-list"; }
1115     }
1116 
1117     /* Support for @<file> in jmod help */
1118     private static final String CMD_FILENAME = "@<filename>";
1119 
1120     /**
1121      * This formatter is adding the @filename option and does the required
1122      * formatting.
1123      */
1124     private static final class JmodHelpFormatter extends BuiltinHelpFormatter {
1125 
1126         private JmodHelpFormatter() { super(80, 2); }
1127 
1128         @Override
1129         public String format(Map<String, ? extends OptionDescriptor> options) {
1130             Map<String, OptionDescriptor> all = new HashMap<>();
1131             all.putAll(options);





1132             all.put(CMD_FILENAME, new OptionDescriptor() {
1133                 @Override
1134                 public Collection<String> options() {
1135                     List<String> ret = new ArrayList<>();
1136                     ret.add(CMD_FILENAME);
1137                     return ret;
1138                 }
1139                 @Override
1140                 public String description() { return getMessage("main.opt.cmdfile"); }
1141                 @Override
1142                 public List<?> defaultValues() { return Collections.emptyList(); }
1143                 @Override
1144                 public boolean isRequired() { return false; }
1145                 @Override
1146                 public boolean acceptsArguments() { return false; }
1147                 @Override
1148                 public boolean requiresArgument() { return false; }
1149                 @Override
1150                 public String argumentDescription() { return null; }
1151                 @Override


1253         OptionSpec<Version> moduleVersion
1254                 = parser.accepts("module-version", getMessage("main.opt.module-version"))
1255                         .withRequiredArg()
1256                         .withValuesConvertedBy(new ModuleVersionConverter());
1257 
1258         OptionSpec<String> osName
1259                 = parser.accepts("os-name", getMessage("main.opt.os-name"))
1260                         .withRequiredArg()
1261                         .describedAs(getMessage("main.opt.os-name.arg"));
1262 
1263         OptionSpec<String> osArch
1264                 = parser.accepts("os-arch", getMessage("main.opt.os-arch"))
1265                         .withRequiredArg()
1266                         .describedAs(getMessage("main.opt.os-arch.arg"));
1267 
1268         OptionSpec<String> osVersion
1269                 = parser.accepts("os-version", getMessage("main.opt.os-version"))
1270                         .withRequiredArg()
1271                         .describedAs(getMessage("main.opt.os-version.arg"));
1272 








1273         OptionSpec<Void> version
1274                 = parser.accepts("version", getMessage("main.opt.version"));
1275 
1276         NonOptionArgumentSpec<String> nonOptions
1277                 = parser.nonOptions();
1278 
1279         try {
1280             OptionSet opts = parser.parse(args);
1281 
1282             if (opts.has(help) || opts.has(version)) {
1283                 options = new Options();
1284                 options.help = opts.has(help);
1285                 options.version = opts.has(version);
1286                 return;  // informational message will be shown
1287             }
1288 
1289             List<String> words = opts.valuesOf(nonOptions);
1290             if (words.isEmpty())
1291                 throw new CommandException("err.missing.mode").showUsage(true);
1292             String verb = words.get(0);


1317                 Path[] dirs = opts.valuesOf(modulePath).toArray(new Path[0]);
1318                 options.moduleFinder = JLMA.newModulePath(Runtime.version(), true, dirs);
1319             }
1320             if (opts.has(moduleVersion))
1321                 options.moduleVersion = opts.valueOf(moduleVersion);
1322             if (opts.has(mainClass))
1323                 options.mainClass = opts.valueOf(mainClass);
1324             if (opts.has(osName))
1325                 options.osName = opts.valueOf(osName);
1326             if (opts.has(osArch))
1327                 options.osArch = opts.valueOf(osArch);
1328             if (opts.has(osVersion))
1329                 options.osVersion = opts.valueOf(osVersion);
1330             if (opts.has(hashModules)) {
1331                 options.modulesToHash = opts.valueOf(hashModules);
1332                 // if storing hashes then the module path is required
1333                 if (options.moduleFinder == null)
1334                     throw new CommandException("err.modulepath.must.be.specified")
1335                             .showUsage(true);
1336             }




1337 
1338             if (options.mode.equals(Mode.HASH)) {
1339                 if (options.moduleFinder == null || options.modulesToHash == null)
1340                     throw new CommandException("err.modulepath.must.be.specified")
1341                             .showUsage(true);
1342             } else {
1343                 if (words.size() <= 1)
1344                     throw new CommandException("err.jmod.must.be.specified").showUsage(true);
1345                 Path path = Paths.get(words.get(1));
1346 
1347                 if (options.mode.equals(Mode.CREATE) && Files.exists(path))
1348                     throw new CommandException("err.file.already.exists", path);
1349                 else if ((options.mode.equals(Mode.LIST) ||
1350                             options.mode.equals(Mode.DESCRIBE))
1351                          && Files.notExists(path))
1352                     throw new CommandException("err.jmod.not.found", path);
1353 
1354                 if (options.dryrun) {
1355                     throw new CommandException("err.invalid.dryrun.option");
1356                 }




  87 import java.util.stream.Stream;
  88 import java.util.zip.ZipEntry;
  89 import java.util.zip.ZipException;
  90 import java.util.zip.ZipFile;
  91 
  92 import jdk.internal.jmod.JmodFile;
  93 import jdk.internal.jmod.JmodFile.Section;
  94 import jdk.internal.joptsimple.BuiltinHelpFormatter;
  95 import jdk.internal.joptsimple.NonOptionArgumentSpec;
  96 import jdk.internal.joptsimple.OptionDescriptor;
  97 import jdk.internal.joptsimple.OptionException;
  98 import jdk.internal.joptsimple.OptionParser;
  99 import jdk.internal.joptsimple.OptionSet;
 100 import jdk.internal.joptsimple.OptionSpec;
 101 import jdk.internal.joptsimple.ValueConverter;
 102 import jdk.internal.loader.ResourceHelper;
 103 import jdk.internal.misc.JavaLangModuleAccess;
 104 import jdk.internal.misc.SharedSecrets;
 105 import jdk.internal.module.ModuleHashes;
 106 import jdk.internal.module.ModuleInfoExtender;
 107 import jdk.internal.module.WarnIfResolvedReason;
 108 import jdk.tools.jlink.internal.Utils;
 109 
 110 import static java.util.stream.Collectors.joining;
 111 
 112 /**
 113  * Implementation for the jmod tool.
 114  */
 115 public class JmodTask {
 116 
 117     static class CommandException extends RuntimeException {
 118         private static final long serialVersionUID = 0L;
 119         boolean showUsage;
 120 
 121         CommandException(String key, Object... args) {
 122             super(getMessageOrKey(key, args));
 123         }
 124 
 125         CommandException showUsage(boolean b) {
 126             showUsage = b;
 127             return this;


 160     };
 161 
 162     static class Options {
 163         Mode mode;
 164         Path jmodFile;
 165         boolean help;
 166         boolean version;
 167         List<Path> classpath;
 168         List<Path> cmds;
 169         List<Path> configs;
 170         List<Path> libs;
 171         List<Path> headerFiles;
 172         List<Path> manPages;
 173         ModuleFinder moduleFinder;
 174         Version moduleVersion;
 175         String mainClass;
 176         String osName;
 177         String osArch;
 178         String osVersion;
 179         Pattern modulesToHash;
 180         boolean doNotResolveByDefault;
 181         WarnIfResolvedReason warnIfResolvedReason = WarnIfResolvedReason.NONE;
 182         boolean dryrun;
 183         List<PathMatcher> excludes;
 184     }
 185 
 186     public int run(String[] args) {
 187 
 188         try {
 189             handleOptions(args);
 190             if (options == null) {
 191                 showUsageSummary();
 192                 return EXIT_CMDERR;
 193             }
 194             if (options.help) {
 195                 showHelp();
 196                 return EXIT_OK;
 197             }
 198             if (options.version) {
 199                 showVersion();
 200                 return EXIT_OK;
 201             }


 310         md.provides().stream()
 311             .sorted(Comparator.comparing(Provides::service))
 312             .forEach(p -> sb.append("\n  provides ").append(p.service())
 313                             .append(" with ")
 314                             .append(toString(p.providers())));
 315 
 316         md.mainClass().ifPresent(v -> sb.append("\n  main-class " + v));
 317 
 318         md.osName().ifPresent(v -> sb.append("\n  operating-system-name " + v));
 319 
 320         md.osArch().ifPresent(v -> sb.append("\n  operating-system-architecture " + v));
 321 
 322         md.osVersion().ifPresent(v -> sb.append("\n  operating-system-version " + v));
 323 
 324         JLMA.hashes(md).ifPresent(
 325             hashes -> hashes.names().stream().sorted().forEach(
 326                 mod -> sb.append("\n  hashes ").append(mod).append(" ")
 327                          .append(hashes.algorithm()).append(" ")
 328                          .append(hashes.hashFor(mod))));
 329 
 330         if (JLMA.doNotResolveByDefault(md))
 331             sb.append("\n  doNotResolveByDefault true");
 332 
 333         WarnIfResolvedReason reason = JLMA.warnIfResolvedReason(md);
 334         if (!reason.equals(WarnIfResolvedReason.NONE))
 335             sb.append("\n  warnIfResolved ").append(reason);
 336 
 337         out.println(sb.toString());
 338     }
 339 
 340     private boolean create() throws IOException {
 341         JmodFileWriter jmod = new JmodFileWriter();
 342 
 343         // create jmod with temporary name to avoid it being examined
 344         // when scanning the module path
 345         Path target = options.jmodFile;
 346         Path tempTarget = target.resolveSibling(target.getFileName() + ".tmp");
 347         try {
 348             try (JmodOutputStream jos = JmodOutputStream.newOutputStream(tempTarget)) {
 349                 jmod.write(jos);
 350             }
 351             Files.move(tempTarget, target);
 352         } catch (Exception e) {
 353             if (Files.exists(tempTarget)) {
 354                 try {
 355                     Files.delete(tempTarget);
 356                 } catch (IOException ioe) {


 360             throw e;
 361         }
 362         return true;
 363     }
 364 
 365     private class JmodFileWriter {
 366         final List<Path> cmds = options.cmds;
 367         final List<Path> libs = options.libs;
 368         final List<Path> configs = options.configs;
 369         final List<Path> classpath = options.classpath;
 370         final List<Path> headerFiles = options.headerFiles;
 371         final List<Path> manPages = options.manPages;
 372 
 373         final Version moduleVersion = options.moduleVersion;
 374         final String mainClass = options.mainClass;
 375         final String osName = options.osName;
 376         final String osArch = options.osArch;
 377         final String osVersion = options.osVersion;
 378         final List<PathMatcher> excludes = options.excludes;
 379         final Hasher hasher = hasher();
 380         final boolean doNotResolveByDefault = options.doNotResolveByDefault;
 381         final WarnIfResolvedReason warnReason = options.warnIfResolvedReason;
 382 
 383         JmodFileWriter() { }
 384 
 385         /**
 386          * Writes the jmod to the given output stream.
 387          */
 388         void write(JmodOutputStream out) throws IOException {
 389             // module-info.class
 390             writeModuleInfo(out, findPackages(classpath));
 391 
 392             // classes
 393             processClasses(out, classpath);
 394 
 395             processSection(out, Section.NATIVE_CMDS, cmds);
 396             processSection(out, Section.NATIVE_LIBS, libs);
 397             processSection(out, Section.CONFIG, configs);
 398             processSection(out, Section.HEADER_FILES, headerFiles);
 399             processSection(out, Section.MAN_PAGES, manPages);
 400 
 401         }


 470                 if (mainClass != null)
 471                     extender.mainClass(mainClass);
 472 
 473                 // --os-name, --os-arch, --os-version
 474                 if (osName != null || osArch != null || osVersion != null)
 475                     extender.targetPlatform(osName, osArch, osVersion);
 476 
 477                 // --module-version
 478                 if (moduleVersion != null)
 479                     extender.version(moduleVersion);
 480 
 481                 if (hasher != null) {
 482                     ModuleHashes moduleHashes = hasher.computeHashes(descriptor.name());
 483                     if (moduleHashes != null) {
 484                         extender.hashes(moduleHashes);
 485                     } else {
 486                         warning("warn.no.module.hashes", descriptor.name());
 487                     }
 488                 }
 489 
 490                 if (doNotResolveByDefault || warnReason != WarnIfResolvedReason.NONE)
 491                     extender.moduleResolution(doNotResolveByDefault, warnReason);
 492 
 493                 // write the (possibly extended or modified) module-info.class
 494                 out.writeEntry(extender.toByteArray(), Section.CLASSES, MODULE_INFO);
 495             }
 496         }
 497 
 498         /*
 499          * Hasher resolves a module graph using the --hash-modules PATTERN
 500          * as the roots.
 501          *
 502          * The jmod file is being created and does not exist in the
 503          * given modulepath.
 504          */
 505         private Hasher hasher() {
 506             if (options.modulesToHash == null)
 507                 return null;
 508 
 509             try {
 510                 Supplier<InputStream> miSupplier = newModuleInfoSupplier();
 511                 if (miSupplier == null) {
 512                     throw new IOException(MODULE_INFO + " not found");


1097 
1098     static class PatternConverter implements ValueConverter<Pattern> {
1099         @Override
1100         public Pattern convert(String value) {
1101             try {
1102                 if (value.startsWith("regex:")) {
1103                     value = value.substring("regex:".length()).trim();
1104                 }
1105 
1106                 return Pattern.compile(value);
1107             } catch (PatternSyntaxException e) {
1108                 throw new CommandException("err.bad.pattern", value);
1109             }
1110         }
1111 
1112         @Override public Class<Pattern> valueType() { return Pattern.class; }
1113 
1114         @Override public String valuePattern() { return "regex-pattern"; }
1115     }
1116 
1117     static class WarnIfResolvedReasonConverter
1118         implements ValueConverter<WarnIfResolvedReason>
1119     {
1120         @Override
1121         public WarnIfResolvedReason convert(String value) {
1122             if (value.equals("deprecated"))
1123                 return WarnIfResolvedReason.DEPRECATED;
1124             else if (value.equals("deprecated-for-removal"))
1125                 return WarnIfResolvedReason.DEPRECATED_FOR_REMOVAL;
1126             else if (value.equals("incubating"))
1127                 return WarnIfResolvedReason.INCUBATING;
1128             else
1129                 throw new CommandException("err.bad.WarnIfResolvedReason", value);
1130         }
1131 
1132         @Override public Class<WarnIfResolvedReason> valueType() {
1133             return WarnIfResolvedReason.class;
1134         }
1135 
1136         @Override public String valuePattern() { return "reason"; }
1137     }
1138 
1139     static class PathMatcherConverter implements ValueConverter<PathMatcher> {
1140         @Override
1141         public PathMatcher convert(String pattern) {
1142             try {
1143                 return Utils.getPathMatcher(FileSystems.getDefault(), pattern);
1144             } catch (PatternSyntaxException e) {
1145                 throw new CommandException("err.bad.pattern", pattern);
1146             }
1147         }
1148 
1149         @Override public Class<PathMatcher> valueType() { return PathMatcher.class; }
1150 
1151         @Override public String valuePattern() { return "pattern-list"; }
1152     }
1153 
1154     /* Support for @<file> in jmod help */
1155     private static final String CMD_FILENAME = "@<filename>";
1156 
1157     /**
1158      * This formatter is adding the @filename option and does the required
1159      * formatting.
1160      */
1161     private static final class JmodHelpFormatter extends BuiltinHelpFormatter {
1162 
1163         private JmodHelpFormatter() { super(80, 2); }
1164 
1165         @Override
1166         public String format(Map<String, ? extends OptionDescriptor> options) {
1167             Map<String, OptionDescriptor> all = new HashMap<>();
1168             all.putAll(options);
1169 
1170             // hidden options
1171             all.remove("do-not-resolve-by-default");
1172             all.remove("warn-if-resolved");
1173 
1174             all.put(CMD_FILENAME, new OptionDescriptor() {
1175                 @Override
1176                 public Collection<String> options() {
1177                     List<String> ret = new ArrayList<>();
1178                     ret.add(CMD_FILENAME);
1179                     return ret;
1180                 }
1181                 @Override
1182                 public String description() { return getMessage("main.opt.cmdfile"); }
1183                 @Override
1184                 public List<?> defaultValues() { return Collections.emptyList(); }
1185                 @Override
1186                 public boolean isRequired() { return false; }
1187                 @Override
1188                 public boolean acceptsArguments() { return false; }
1189                 @Override
1190                 public boolean requiresArgument() { return false; }
1191                 @Override
1192                 public String argumentDescription() { return null; }
1193                 @Override


1295         OptionSpec<Version> moduleVersion
1296                 = parser.accepts("module-version", getMessage("main.opt.module-version"))
1297                         .withRequiredArg()
1298                         .withValuesConvertedBy(new ModuleVersionConverter());
1299 
1300         OptionSpec<String> osName
1301                 = parser.accepts("os-name", getMessage("main.opt.os-name"))
1302                         .withRequiredArg()
1303                         .describedAs(getMessage("main.opt.os-name.arg"));
1304 
1305         OptionSpec<String> osArch
1306                 = parser.accepts("os-arch", getMessage("main.opt.os-arch"))
1307                         .withRequiredArg()
1308                         .describedAs(getMessage("main.opt.os-arch.arg"));
1309 
1310         OptionSpec<String> osVersion
1311                 = parser.accepts("os-version", getMessage("main.opt.os-version"))
1312                         .withRequiredArg()
1313                         .describedAs(getMessage("main.opt.os-version.arg"));
1314 
1315         OptionSpec<Void> doNotResolveByDefault
1316                 = parser.accepts("do-not-resolve-by-default");
1317 
1318         OptionSpec<WarnIfResolvedReason> warnIfResolved
1319                 = parser.accepts("warn-if-resolved")
1320                         .withRequiredArg()
1321                         .withValuesConvertedBy(new WarnIfResolvedReasonConverter());
1322 
1323         OptionSpec<Void> version
1324                 = parser.accepts("version", getMessage("main.opt.version"));
1325 
1326         NonOptionArgumentSpec<String> nonOptions
1327                 = parser.nonOptions();
1328 
1329         try {
1330             OptionSet opts = parser.parse(args);
1331 
1332             if (opts.has(help) || opts.has(version)) {
1333                 options = new Options();
1334                 options.help = opts.has(help);
1335                 options.version = opts.has(version);
1336                 return;  // informational message will be shown
1337             }
1338 
1339             List<String> words = opts.valuesOf(nonOptions);
1340             if (words.isEmpty())
1341                 throw new CommandException("err.missing.mode").showUsage(true);
1342             String verb = words.get(0);


1367                 Path[] dirs = opts.valuesOf(modulePath).toArray(new Path[0]);
1368                 options.moduleFinder = JLMA.newModulePath(Runtime.version(), true, dirs);
1369             }
1370             if (opts.has(moduleVersion))
1371                 options.moduleVersion = opts.valueOf(moduleVersion);
1372             if (opts.has(mainClass))
1373                 options.mainClass = opts.valueOf(mainClass);
1374             if (opts.has(osName))
1375                 options.osName = opts.valueOf(osName);
1376             if (opts.has(osArch))
1377                 options.osArch = opts.valueOf(osArch);
1378             if (opts.has(osVersion))
1379                 options.osVersion = opts.valueOf(osVersion);
1380             if (opts.has(hashModules)) {
1381                 options.modulesToHash = opts.valueOf(hashModules);
1382                 // if storing hashes then the module path is required
1383                 if (options.moduleFinder == null)
1384                     throw new CommandException("err.modulepath.must.be.specified")
1385                             .showUsage(true);
1386             }
1387             if (opts.has(doNotResolveByDefault))
1388                 options.doNotResolveByDefault = true;
1389             if (opts.has(warnIfResolved))
1390                 options.warnIfResolvedReason = opts.valueOf(warnIfResolved);
1391 
1392             if (options.mode.equals(Mode.HASH)) {
1393                 if (options.moduleFinder == null || options.modulesToHash == null)
1394                     throw new CommandException("err.modulepath.must.be.specified")
1395                             .showUsage(true);
1396             } else {
1397                 if (words.size() <= 1)
1398                     throw new CommandException("err.jmod.must.be.specified").showUsage(true);
1399                 Path path = Paths.get(words.get(1));
1400 
1401                 if (options.mode.equals(Mode.CREATE) && Files.exists(path))
1402                     throw new CommandException("err.file.already.exists", path);
1403                 else if ((options.mode.equals(Mode.LIST) ||
1404                             options.mode.equals(Mode.DESCRIBE))
1405                          && Files.notExists(path))
1406                     throw new CommandException("err.jmod.not.found", path);
1407 
1408                 if (options.dryrun) {
1409                     throw new CommandException("err.invalid.dryrun.option");
1410                 }


< prev index next >