--- old/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java 2016-12-18 17:39:05.000000000 -0800 +++ new/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java 2016-12-18 17:39:05.000000000 -0800 @@ -306,6 +306,13 @@ fail(name + ": cannot be loaded from application module path"); } } + + // check if module specified in --patch-module is present + for (String mn: patcher.patchedModules()) { + if (!cf.findModule(mn).isPresent()) { + warnUnknownModule(PATCH_MODULE, mn); + } + } } @@ -464,7 +471,7 @@ String mn = e.getKey(); Optional om = bootLayer.findModule(mn); if (!om.isPresent()) { - warn("Unknown module: " + mn); + warnUnknownModule(ADD_READS, mn); continue; } Module m = om.get(); @@ -478,7 +485,7 @@ if (om.isPresent()) { Modules.addReads(m, om.get()); } else { - warn("Unknown module: " + name); + warnUnknownModule(ADD_READS, name); } } } @@ -510,24 +517,25 @@ Map> map, boolean opens) { + String option = opens ? ADD_OPENS : ADD_EXPORTS; for (Map.Entry> e : map.entrySet()) { // the key is $MODULE/$PACKAGE String key = e.getKey(); String[] s = key.split("/"); if (s.length != 2) - fail("Unable to parse as /: " + key); + fail(unableToParse(option, "/", key)); String mn = s[0]; String pn = s[1]; if (mn.isEmpty() || pn.isEmpty()) - fail("Module and package name must be specified: " + key); + fail(unableToParse(option, "/", key)); // The exporting module is in the boot layer Module m; Optional om = bootLayer.findModule(mn); if (!om.isPresent()) { - warn("Unknown module: " + mn); + warnUnknownModule(option, mn); continue; } @@ -549,7 +557,7 @@ if (om.isPresent()) { other = om.get(); } else { - warn("Unknown module: " + name); + warnUnknownModule(option, name); continue; } } @@ -593,24 +601,30 @@ int pos = value.indexOf('='); if (pos == -1) - fail("Unable to parse as =: " + value); + fail(unableToParse(option(prefix), "=", value)); if (pos == 0) - fail("Missing module name in: " + value); + fail(unableToParse(option(prefix), "=", value)); // key is or / String key = value.substring(0, pos); String rhs = value.substring(pos+1); if (rhs.isEmpty()) - fail("Unable to parse as =: " + value); + fail(unableToParse(option(prefix), "=", value)); // value is (,)* or ()* if (!allowDuplicates && map.containsKey(key)) - fail(key + " specified more than once"); + fail(key + " specified more than once in " + option(prefix)); List values = map.computeIfAbsent(key, k -> new ArrayList<>()); + int ntargets = 0; for (String s : rhs.split(regex)) { - if (s.length() > 0) values.add(s); + if (s.length() > 0) { + values.add(s); + ntargets++; + } } + if (ntargets == 0) + fail("Target must be specified: " + option(prefix) + " " + value); index++; value = getAndRemoveProperty(prefix + index); @@ -672,6 +686,42 @@ System.err.println("WARNING: " + m); } + static void warnUnknownModule(String option, String mn) { + warn("Unknown module: " + mn + " specified in " + option); + } + + static String unableToParse(String option, String text, String value) { + return "Unable to parse " + option + " " + text + ": " + value; + } + + private static final String ADD_MODULES = "--add-modules"; + private static final String ADD_EXPORTS = "--add-exports"; + private static final String ADD_OPENS = "--add-opens"; + private static final String ADD_READS = "--add-reads"; + private static final String PATCH_MODULE = "--patch-module"; + + + /* + * Returns the command-line option name corresponds to the specified + * system property prefix. + */ + static String option(String prefix) { + switch (prefix) { + case "jdk.module.addexports.": + return ADD_EXPORTS; + case "jdk.module.addopens.": + return ADD_OPENS; + case "jdk.module.addreads.": + return ADD_READS; + case "jdk.module.patch.": + return PATCH_MODULE; + case "jdk.module.addmods.": + return ADD_MODULES; + default: + throw new IllegalArgumentException(prefix); + } + } + static class PerfCounters { static PerfCounter systemModulesTime