--- a/jdk/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java Wed Nov 23 16:16:35 2016 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java Thu Dec 01 08:57:53 2016 +0000
@@ -37,9 +37,11 @@
import java.net.URI;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
@@ -81,10 +83,20 @@
// the token for "all modules on the module path"
private static final String ALL_MODULE_PATH = "ALL-MODULE-PATH";
+ // The ModulePatcher for the initial configuration
+ private static final ModulePatcher patcher = initModulePatcher();
+
// ModuleFinder for the initial configuration
private static ModuleFinder initialFinder;
/**
+ * Returns the ModulePatcher for the initial configuration.
+ */
+ public static ModulePatcher patcher() {
+ return patcher;
+ }
+
+ /**
* Returns the ModuleFinder for the initial configuration
*/
public static ModuleFinder finder() {
@@ -101,7 +113,7 @@
long t0 = System.nanoTime();
- // system modules
+ // system modules (may be patched)
ModuleFinder systemModules = ModuleFinder.ofSystem();
PerfCounters.systemModulesTime.addElapsedTimeFrom(t0);
@@ -247,7 +259,7 @@
if (baseUri.getScheme().equals("jrt") // toLowerCase not needed here
&& (upgradeModulePath == null)
&& (appModulePath == null)
- && (!ModulePatcher.isBootLayerPatched())) {
+ && (patcher.isEmpty())) {
needPostResolutionChecks = false;
}
@@ -314,9 +326,9 @@
PerfCounters.loadModulesTime.addElapsedTimeFrom(t5);
- // --add-reads and --add-exports
+ // --add-reads, -add-exports/-add-opens
addExtraReads(bootLayer);
- addExtraExports(bootLayer);
+ addExtraExportsAndOpens(bootLayer);
// total time to initialize
PerfCounters.bootstrapTime.addElapsedTimeFrom(t0);
@@ -389,6 +401,18 @@
}
}
+
+ /**
+ * Initialize the module patcher for the initial configuration passed on the
+ * value of the --patch-module options.
+ */
+ private static ModulePatcher initModulePatcher() {
+ Map<String, List<String>> map = decode("jdk.module.patch.",
+ File.pathSeparator,
+ false);
+ return new ModulePatcher(map);
+ }
+
/**
* Returns the set of module names specified via --add-modules options
* on the command line
@@ -408,7 +432,6 @@
for (String s : value.split(",")) {
if (s.length() > 0) modules.add(s);
}
-
index++;
value = getAndRemoveProperty(prefix + index);
}
@@ -423,9 +446,11 @@
private static void addExtraReads(Layer bootLayer) {
// decode the command line options
- Map<String, Set<String>> map = decode("jdk.module.addreads.");
+ Map<String, List<String>> map = decode("jdk.module.addreads.");
+ if (map.isEmpty())
+ return;
- for (Map.Entry<String, Set<String>> e : map.entrySet()) {
+ for (Map.Entry<String, List<String>> e : map.entrySet()) {
// the key is $MODULE
String mn = e.getKey();
@@ -448,22 +473,36 @@
warn("Unknown module: " + name);
}
}
-
}
}
}
-
/**
- * Process the --add-exports options to add any additional read edges that
- * are specified on the command-line.
+ * Process the --add-exports and --add-opens options to export/open
+ * additional packages specified on the command-line.
*/
- private static void addExtraExports(Layer bootLayer) {
+ private static void addExtraExportsAndOpens(Layer bootLayer) {
+
+ // --add-exports
+ String prefix = "jdk.module.addexports.";
+ Map<String, List<String>> extraExports = decode(prefix);
+ if (!extraExports.isEmpty()) {
+ addExtraExportsOrOpens(bootLayer, extraExports, false);
+ }
- // decode the command line options
- Map<String, Set<String>> map = decode("jdk.module.addexports.");
+ // --add-opens
+ prefix = "jdk.module.addopens.";
+ Map<String, List<String>> extraOpens = decode(prefix);
+ if (!extraOpens.isEmpty()) {
+ addExtraExportsOrOpens(bootLayer, extraOpens, true);
+ }
+ }
- for (Map.Entry<String, Set<String>> e : map.entrySet()) {
+ private static void addExtraExportsOrOpens(Layer bootLayer,
+ Map<String, List<String>> map,
+ boolean opens)
+ {
+ for (Map.Entry<String, List<String>> e : map.entrySet()) {
// the key is $MODULE/$PACKAGE
String key = e.getKey();
@@ -507,28 +546,40 @@
}
}
if (allUnnamed) {
- Modules.addExportsToAllUnnamed(m, pn);
+ if (opens) {
+ Modules.addOpensToAllUnnamed(m, pn);
+ } else {
+ Modules.addExportsToAllUnnamed(m, pn);
+ }
} else {
- Modules.addExports(m, pn, other);
+ if (opens) {
+ Modules.addOpens(m, pn, other);
+ } else {
+ Modules.addExports(m, pn, other);
+ }
}
+
}
}
}
-
/**
- * Decodes the values of --add-reads or --add-exports options
+ * Decodes the values of --add-reads, -add-exports, --add-opens or
+ * --patch-modules options that are encoded in system properties.
*
- * The format of the options is: $KEY=$MODULE(,$MODULE)*
+ * @param prefix the system property prefix
+ * @praam regex the regex for splitting the RHS of the option value
*/
- private static Map<String, Set<String>> decode(String prefix) {
+ private static Map<String, List<String>> decode(String prefix,
+ String regex,
+ boolean allowDuplicates) {
int index = 0;
// the system property is removed after decoding
String value = getAndRemoveProperty(prefix + index);
if (value == null)
return Collections.emptyMap();
- Map<String, Set<String>> map = new HashMap<>();
+ Map<String, List<String>> map = new HashMap<>();
while (value != null) {
@@ -545,8 +596,11 @@
if (rhs.isEmpty())
fail("Unable to parse: " + value);
- Set<String> values = map.computeIfAbsent(key, k -> new HashSet<>());
- for (String s : rhs.split(",")) {
+ // value is <module>(,<module>)* or <file>(<pathsep><file>)*
+ if (!allowDuplicates && map.containsKey(key))
+ fail(key + " specified more than once");
+ List<String> values = map.computeIfAbsent(key, k -> new ArrayList<>());
+ for (String s : rhs.split(regex)) {
if (s.length() > 0) values.add(s);
}
@@ -558,6 +612,14 @@
}
/**
+ * Decodes the values of --add-reads, -add-exports or --add-opens
+ * which use the "," to separate the RHS of the option value.
+ */
+ private static Map<String, List<String>> decode(String prefix) {
+ return decode(prefix, ",", true);
+ }
+
+ /**
* Gets and remove the named system property
*/
private static String getAndRemoveProperty(String key) {