54 * Initializes/boots the module system. |
54 * Initializes/boots the module system. |
55 * |
55 * |
56 * The {@link #boot() boot} method is called early in the startup to initialize |
56 * The {@link #boot() boot} method is called early in the startup to initialize |
57 * the module system. In summary, the boot method creates a Configuration by |
57 * the module system. In summary, the boot method creates a Configuration by |
58 * resolving a set of module names specified via the launcher (or equivalent) |
58 * resolving a set of module names specified via the launcher (or equivalent) |
59 * -m and -addmods options. The modules are located on a module path that is |
59 * -m and --add-modules options. The modules are located on a module path that |
60 * constructed from the upgrade module path, system modules, and application |
60 * is constructed from the upgrade module path, system modules, and application |
61 * module path. The Configuration is instantiated as the boot Layer with each |
61 * module path. The Configuration is instantiated as the boot Layer with each |
62 * module in the the configuration defined to one of the built-in class loaders. |
62 * module in the the configuration defined to one of the built-in class loaders. |
63 */ |
63 */ |
64 |
64 |
65 public final class ModuleBootstrap { |
65 public final class ModuleBootstrap { |
125 PerfCounters.defineBaseTime.addElapsedTimeFrom(t1); |
125 PerfCounters.defineBaseTime.addElapsedTimeFrom(t1); |
126 |
126 |
127 |
127 |
128 long t2 = System.nanoTime(); |
128 long t2 = System.nanoTime(); |
129 |
129 |
130 // -upgrademodulepath option specified to launcher |
130 // --upgrade-module-path option specified to launcher |
131 ModuleFinder upgradeModulePath |
131 ModuleFinder upgradeModulePath |
132 = createModulePathFinder("jdk.upgrade.module.path"); |
132 = createModulePathFinder("jdk.module.upgrade.path"); |
133 if (upgradeModulePath != null) |
133 if (upgradeModulePath != null) |
134 systemModules = ModuleFinder.compose(upgradeModulePath, systemModules); |
134 systemModules = ModuleFinder.compose(upgradeModulePath, systemModules); |
135 |
135 |
136 // -modulepath option specified to the launcher |
136 // --module-path option specified to the launcher |
137 ModuleFinder appModulePath = createModulePathFinder("jdk.module.path"); |
137 ModuleFinder appModulePath = createModulePathFinder("jdk.module.path"); |
138 |
138 |
139 // The module finder: [-upgrademodulepath] system [-modulepath] |
139 // The module finder: [--upgrade-module-path] system [--module-path] |
140 ModuleFinder finder = systemModules; |
140 ModuleFinder finder = systemModules; |
141 if (appModulePath != null) |
141 if (appModulePath != null) |
142 finder = ModuleFinder.compose(finder, appModulePath); |
142 finder = ModuleFinder.compose(finder, appModulePath); |
143 |
143 |
144 // The root modules to resolve |
144 // The root modules to resolve |
147 // launcher -m option to specify the main/initial module |
147 // launcher -m option to specify the main/initial module |
148 String mainModule = System.getProperty("jdk.module.main"); |
148 String mainModule = System.getProperty("jdk.module.main"); |
149 if (mainModule != null) |
149 if (mainModule != null) |
150 roots.add(mainModule); |
150 roots.add(mainModule); |
151 |
151 |
152 // additional module(s) specified by -addmods |
152 // additional module(s) specified by --add-modules |
153 boolean addAllDefaultModules = false; |
153 boolean addAllDefaultModules = false; |
154 boolean addAllSystemModules = false; |
154 boolean addAllSystemModules = false; |
155 boolean addAllApplicationModules = false; |
155 boolean addAllApplicationModules = false; |
156 String propValue = System.getProperty("jdk.launcher.addmods"); |
156 String propValue = getAndRemoveProperty("jdk.module.addmods"); |
157 if (propValue != null) { |
157 if (propValue != null) { |
158 for (String mod: propValue.split(",")) { |
158 for (String mod: propValue.split(",")) { |
159 switch (mod) { |
159 switch (mod) { |
160 case ALL_DEFAULT: |
160 case ALL_DEFAULT: |
161 addAllDefaultModules = true; |
161 addAllDefaultModules = true; |
214 } |
214 } |
215 } |
215 } |
216 } |
216 } |
217 } |
217 } |
218 |
218 |
219 // If `-addmods ALL-SYSTEM` is specified then all observable system |
219 // If `--add-modules ALL-SYSTEM` is specified then all observable system |
220 // modules will be resolved. |
220 // modules will be resolved. |
221 if (addAllSystemModules) { |
221 if (addAllSystemModules) { |
222 ModuleFinder f = finder; // observable modules |
222 ModuleFinder f = finder; // observable modules |
223 systemModules.findAll() |
223 systemModules.findAll() |
224 .stream() |
224 .stream() |
226 .map(ModuleDescriptor::name) |
226 .map(ModuleDescriptor::name) |
227 .filter(mn -> f.find(mn).isPresent()) // observable |
227 .filter(mn -> f.find(mn).isPresent()) // observable |
228 .forEach(mn -> roots.add(mn)); |
228 .forEach(mn -> roots.add(mn)); |
229 } |
229 } |
230 |
230 |
231 // If `-addmods ALL-MODULE-PATH` is specified then all observable |
231 // If `--add-modules ALL-MODULE-PATH` is specified then all observable |
232 // modules on the application module path will be resolved. |
232 // modules on the application module path will be resolved. |
233 if (appModulePath != null && addAllApplicationModules) { |
233 if (appModulePath != null && addAllApplicationModules) { |
234 ModuleFinder f = finder; // observable modules |
234 ModuleFinder f = finder; // observable modules |
235 appModulePath.findAll() |
235 appModulePath.findAll() |
236 .stream() |
236 .stream() |
237 .map(ModuleReference::descriptor) |
237 .map(ModuleReference::descriptor) |
238 .map(ModuleDescriptor::name) |
238 .map(ModuleDescriptor::name) |
248 // determine if post resolution checks are needed |
248 // determine if post resolution checks are needed |
249 boolean needPostResolutionChecks = true; |
249 boolean needPostResolutionChecks = true; |
250 if (baseUri.getScheme().equals("jrt") // toLowerCase not needed here |
250 if (baseUri.getScheme().equals("jrt") // toLowerCase not needed here |
251 && (upgradeModulePath == null) |
251 && (upgradeModulePath == null) |
252 && (appModulePath == null) |
252 && (appModulePath == null) |
253 && (System.getProperty("jdk.launcher.patch.0") == null)) { |
253 && (!ModulePatcher.isBootLayerPatched())) { |
254 needPostResolutionChecks = false; |
254 needPostResolutionChecks = false; |
255 } |
255 } |
256 |
256 |
257 PrintStream traceOutput = null; |
257 PrintStream traceOutput = null; |
258 if (Boolean.getBoolean("jdk.launcher.traceResolver")) |
258 if (Boolean.getBoolean("jdk.launcher.traceResolver")) |
315 } |
315 } |
316 |
316 |
317 PerfCounters.loadModulesTime.addElapsedTimeFrom(t5); |
317 PerfCounters.loadModulesTime.addElapsedTimeFrom(t5); |
318 |
318 |
319 |
319 |
320 // -XaddReads and -XaddExports |
320 // --add-reads and --add-exports |
321 addExtraReads(bootLayer); |
321 addExtraReads(bootLayer); |
322 addExtraExports(bootLayer); |
322 addExtraExports(bootLayer); |
323 |
323 |
324 // total time to initialize |
324 // total time to initialize |
325 PerfCounters.bootstrapTime.addElapsedTimeFrom(t0); |
325 PerfCounters.bootstrapTime.addElapsedTimeFrom(t0); |
392 } |
392 } |
393 } |
393 } |
394 |
394 |
395 |
395 |
396 /** |
396 /** |
397 * Process the -XaddReads options to add any additional read edges that |
397 * Process the --add-reads options to add any additional read edges that |
398 * are specified on the command-line. |
398 * are specified on the command-line. |
399 */ |
399 */ |
400 private static void addExtraReads(Layer bootLayer) { |
400 private static void addExtraReads(Layer bootLayer) { |
401 |
401 |
402 // decode the command line options |
402 // decode the command line options |
403 Map<String, Set<String>> map = decode("jdk.launcher.addreads."); |
403 Map<String, Set<String>> map = decode("jdk.module.addreads."); |
404 |
404 |
405 for (Map.Entry<String, Set<String>> e : map.entrySet()) { |
405 for (Map.Entry<String, Set<String>> e : map.entrySet()) { |
406 |
406 |
407 // the key is $MODULE |
407 // the key is $MODULE |
408 String mn = e.getKey(); |
408 String mn = e.getKey(); |
429 } |
429 } |
430 } |
430 } |
431 |
431 |
432 |
432 |
433 /** |
433 /** |
434 * Process the -XaddExports options to add any additional read edges that |
434 * Process the --add-exports options to add any additional read edges that |
435 * are specified on the command-line. |
435 * are specified on the command-line. |
436 */ |
436 */ |
437 private static void addExtraExports(Layer bootLayer) { |
437 private static void addExtraExports(Layer bootLayer) { |
438 |
438 |
439 // decode the command line options |
439 // decode the command line options |
440 Map<String, Set<String>> map = decode("jdk.launcher.addexports."); |
440 Map<String, Set<String>> map = decode("jdk.module.addexports."); |
441 |
441 |
442 for (Map.Entry<String, Set<String>> e : map.entrySet()) { |
442 for (Map.Entry<String, Set<String>> e : map.entrySet()) { |
443 |
443 |
444 // the key is $MODULE/$PACKAGE |
444 // the key is $MODULE/$PACKAGE |
445 String key = e.getKey(); |
445 String key = e.getKey(); |
481 } |
481 } |
482 } |
482 } |
483 |
483 |
484 |
484 |
485 /** |
485 /** |
486 * Decodes the values of -XaddReads or -XaddExports options |
486 * Decodes the values of --add-reads or --add-exports options |
487 * |
487 * |
488 * The format of the options is: $KEY=$MODULE(,$MODULE)* |
488 * The format of the options is: $KEY=$MODULE(,$MODULE)* |
489 */ |
489 */ |
490 private static Map<String, Set<String>> decode(String prefix) { |
490 private static Map<String, Set<String>> decode(String prefix) { |
491 int index = 0; |
491 int index = 0; |
492 String value = System.getProperty(prefix + index); |
492 // the system property is removed after decoding |
|
493 String value = getAndRemoveProperty(prefix + index); |
493 if (value == null) |
494 if (value == null) |
494 return Collections.emptyMap(); |
495 return Collections.emptyMap(); |
495 |
496 |
496 Map<String, Set<String>> map = new HashMap<>(); |
497 Map<String, Set<String>> map = new HashMap<>(); |
497 |
498 |
520 for (String s : rhs.split(",")) { |
521 for (String s : rhs.split(",")) { |
521 if (s.length() > 0) values.add(s); |
522 if (s.length() > 0) values.add(s); |
522 } |
523 } |
523 |
524 |
524 index++; |
525 index++; |
525 value = System.getProperty(prefix + index); |
526 value = getAndRemoveProperty(prefix + index); |
526 } |
527 } |
527 |
528 |
528 return map; |
529 return map; |
529 } |
530 } |
530 |
531 |
|
532 /** |
|
533 * Gets and remove the named system property |
|
534 */ |
|
535 private static String getAndRemoveProperty(String key) { |
|
536 return (String)System.getProperties().remove(key); |
|
537 } |
531 |
538 |
532 /** |
539 /** |
533 * Throws a RuntimeException with the given message |
540 * Throws a RuntimeException with the given message |
534 */ |
541 */ |
535 static void fail(String m) { |
542 static void fail(String m) { |