1 /*
2 * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
123 * Returns the ModuleFinder for the initial configuration.
124 *
125 * @apiNote Used to support "{@code java --list-modules}".
126 */
127 public static ModuleFinder limitedFinder() {
128 ModuleFinder finder = limitedFinder;
129 if (finder == null) {
130 return unlimitedFinder();
131 } else {
132 return finder;
133 }
134 }
135
136 /**
137 * Initialize the module system, returning the boot layer.
138 *
139 * @see java.lang.System#initPhase2(boolean, boolean)
140 */
141 public static ModuleLayer boot() throws Exception {
142
143 // Step 0: Command line options
144
145 long t0 = System.nanoTime();
146
147 ModuleFinder upgradeModulePath = finderFor("jdk.module.upgrade.path");
148 ModuleFinder appModulePath = finderFor("jdk.module.path");
149 boolean isPatched = patcher.hasPatches();
150
151 String mainModule = System.getProperty("jdk.module.main");
152 Set<String> addModules = addModules();
153 Set<String> limitModules = limitModules();
154
155 PrintStream traceOutput = null;
156 String trace = getAndRemoveProperty("jdk.module.showModuleResolution");
157 if (trace != null && Boolean.parseBoolean(trace))
158 traceOutput = System.out;
159
160
161 // Step 1: The observable system modules, either all system modules
162 // or the system modules pre-generated for the initial module (the
163 // initial module may be the unnamed module). If the system modules
164 // are pre-generated for the initial module then resolution can be
165 // skipped.
166
167 long t1 = System.nanoTime();
168
169 SystemModules systemModules = null;
170 ModuleFinder systemModuleFinder;
171
172 boolean haveModulePath = (appModulePath != null || upgradeModulePath != null);
173 boolean needResolution = true;
174 boolean canArchive = false;
175 boolean hasSplitPackages;
176 boolean hasIncubatorModules;
177
178 // If the java heap was archived at CDS dump time and the environment
179 // at dump time matches the current environment then use the archived
180 // system modules and finder.
181 ArchivedModuleGraph archivedModuleGraph = ArchivedModuleGraph.get(mainModule);
182 if (archivedModuleGraph != null
183 && !haveModulePath
184 && addModules.isEmpty()
185 && limitModules.isEmpty()
186 && !isPatched) {
187 systemModuleFinder = archivedModuleGraph.finder();
188 hasSplitPackages = archivedModuleGraph.hasSplitPackages();
198 }
199 if (systemModules == null) {
200 // all system modules are observable
201 systemModules = SystemModuleFinders.allSystemModules();
202 }
203 if (systemModules != null) {
204 // images build
205 systemModuleFinder = SystemModuleFinders.of(systemModules);
206 } else {
207 // exploded build or testing
208 systemModules = new ExplodedSystemModules();
209 systemModuleFinder = SystemModuleFinders.ofSystem();
210 }
211
212 hasSplitPackages = systemModules.hasSplitPackages();
213 hasIncubatorModules = systemModules.hasIncubatorModules();
214 // not using the archived module graph - avoid accidental use
215 archivedModuleGraph = null;
216 }
217
218 Counters.add("jdk.module.boot.1.systemModulesTime", t1);
219
220
221 // Step 2: Define and load java.base. This patches all classes loaded
222 // to date so that they are members of java.base. Once java.base is
223 // loaded then resources in java.base are available for error messages
224 // needed from here on.
225
226 long t2 = System.nanoTime();
227
228 ModuleReference base = systemModuleFinder.find(JAVA_BASE).orElse(null);
229 if (base == null)
230 throw new InternalError(JAVA_BASE + " not found");
231 URI baseUri = base.location().orElse(null);
232 if (baseUri == null)
233 throw new InternalError(JAVA_BASE + " does not have a location");
234 BootLoader.loadModule(base);
235 Modules.defineModule(null, base.descriptor(), baseUri);
236
237 Counters.add("jdk.module.boot.2.defineBaseTime", t2);
238
239
240 // Step 2a: Scan all modules when --validate-modules specified
241
242 if (getAndRemoveProperty("jdk.module.validation") != null) {
243 int errors = ModulePathValidator.scanAllModules(System.out);
244 if (errors > 0) {
245 fail("Validation of module path failed");
246 }
247 }
248
249
250 // Step 3: If resolution is needed then create the module finder and
251 // the set of root modules to resolve.
252
253 long t3 = System.nanoTime();
254
255 ModuleFinder savedModuleFinder = null;
256 ModuleFinder finder;
257 Set<String> roots;
258 if (needResolution) {
259
260 // upgraded modules override the modules in the run-time image
261 if (upgradeModulePath != null)
262 systemModuleFinder = ModuleFinder.compose(upgradeModulePath,
263 systemModuleFinder);
264
265 // The module finder: [--upgrade-module-path] system [--module-path]
266 if (appModulePath != null) {
267 finder = ModuleFinder.compose(systemModuleFinder, appModulePath);
268 } else {
269 finder = systemModuleFinder;
270 }
271
272 // The root modules to resolve
273 roots = new HashSet<>();
274
324 .forEach(mn -> roots.add(mn));
325 }
326
327 // If `--add-modules ALL-MODULE-PATH` is specified then all observable
328 // modules on the application module path will be resolved.
329 if (appModulePath != null && addAllApplicationModules) {
330 ModuleFinder f = finder; // observable modules
331 appModulePath.findAll()
332 .stream()
333 .map(ModuleReference::descriptor)
334 .map(ModuleDescriptor::name)
335 .filter(mn -> f.find(mn).isPresent()) // observable
336 .forEach(mn -> roots.add(mn));
337 }
338 } else {
339 // no resolution case
340 finder = systemModuleFinder;
341 roots = null;
342 }
343
344 Counters.add("jdk.module.boot.3.optionsAndRootsTime", t3);
345
346 // Step 4: Resolve the root modules, with service binding, to create
347 // the configuration for the boot layer. If resolution is not needed
348 // then create the configuration for the boot layer from the
349 // readability graph created at link time.
350
351 long t4 = System.nanoTime();
352
353 Configuration cf;
354 if (needResolution) {
355 cf = Modules.newBootLayerConfiguration(finder, roots, traceOutput);
356 } else {
357 if (archivedModuleGraph != null) {
358 cf = archivedModuleGraph.configuration();
359 } else {
360 Map<String, Set<String>> map = systemModules.moduleReads();
361 cf = JLMA.newConfiguration(systemModuleFinder, map);
362 }
363 }
364
365 // check that modules specified to --patch-module are resolved
366 if (isPatched) {
367 patcher.patchedModules()
368 .stream()
369 .filter(mn -> !cf.findModule(mn).isPresent())
370 .forEach(mn -> warnUnknownModule(PATCH_MODULE, mn));
371 }
372
373 Counters.add("jdk.module.boot.4.resolveTime", t4);
374
375
376 // Step 5: Map the modules in the configuration to class loaders.
377 // The static configuration provides the mapping of standard and JDK
378 // modules to the boot and platform loaders. All other modules (JDK
379 // tool modules, and both explicit and automatic modules on the
380 // application module path) are defined to the application class
381 // loader.
382
383 long t5 = System.nanoTime();
384
385 // mapping of modules to class loaders
386 Function<String, ClassLoader> clf = ModuleLoaderMap.mappingFunction(cf);
387
388 // check that all modules to be mapped to the boot loader will be
389 // loaded from the runtime image
390 if (haveModulePath) {
391 for (ResolvedModule resolvedModule : cf.modules()) {
392 ModuleReference mref = resolvedModule.reference();
393 String name = mref.descriptor().name();
394 ClassLoader cl = clf.apply(name);
395 if (cl == null) {
396 if (upgradeModulePath != null
397 && upgradeModulePath.find(name).isPresent())
398 fail(name + ": cannot be loaded from upgrade module path");
399 if (!systemModuleFinder.find(name).isPresent())
400 fail(name + ": cannot be loaded from application module path");
401 }
402 }
403 }
404
405 // check for split packages in the modules mapped to the built-in loaders
406 if (hasSplitPackages || isPatched || haveModulePath) {
407 checkSplitPackages(cf, clf);
408 }
409
410 // load/register the modules with the built-in class loaders
411 loadModules(cf, clf);
412
413 Counters.add("jdk.module.boot.5.loadModulesTime", t5);
414
415
416 // Step 6: Define all modules to the VM
417
418 long t6 = System.nanoTime();
419 ModuleLayer bootLayer = ModuleLayer.empty().defineModules(cf, clf);
420 Counters.add("jdk.module.boot.6.layerCreateTime", t6);
421
422
423 // Step 7: Miscellaneous
424
425 // check incubating status
426 if (hasIncubatorModules || haveModulePath) {
427 checkIncubatingStatus(cf);
428 }
429
430 // --add-reads, --add-exports/--add-opens, and --illegal-access
431 long t7 = System.nanoTime();
432 addExtraReads(bootLayer);
433 boolean extraExportsOrOpens = addExtraExportsAndOpens(bootLayer);
434
435 Map<String, Set<String>> concealedPackagesToOpen;
436 Map<String, Set<String>> exportedPackagesToOpen;
437 if (archivedModuleGraph != null) {
438 concealedPackagesToOpen = archivedModuleGraph.concealedPackagesToOpen();
439 exportedPackagesToOpen = archivedModuleGraph.exportedPackagesToOpen();
440 } else {
441 concealedPackagesToOpen = systemModules.concealedPackagesToOpen();
442 exportedPackagesToOpen = systemModules.exportedPackagesToOpen();
443 }
444 addIllegalAccess(upgradeModulePath,
445 concealedPackagesToOpen,
446 exportedPackagesToOpen,
447 bootLayer,
448 extraExportsOrOpens);
449 Counters.add("jdk.module.boot.7.adjustModulesTime", t7);
450
451 // save module finders for later use
452 if (savedModuleFinder != null) {
453 unlimitedFinder = new SafeModuleFinder(savedModuleFinder);
454 if (savedModuleFinder != finder)
455 limitedFinder = new SafeModuleFinder(finder);
456 }
457
458 // Module graph can be archived at CDS dump time. Only allow the
459 // unnamed module case for now.
460 if (canArchive && (mainModule == null)) {
461 ArchivedModuleGraph.archive(mainModule,
462 hasSplitPackages,
463 hasIncubatorModules,
464 systemModuleFinder,
465 cf,
466 concealedPackagesToOpen,
467 exportedPackagesToOpen);
468 }
469
470 // total time to initialize
471 Counters.add("jdk.module.boot.totalTime", t0);
472 Counters.publish();
473
474 return bootLayer;
475 }
476
477 /**
478 * Load/register the modules to the built-in class loaders.
479 */
480 private static void loadModules(Configuration cf,
481 Function<String, ClassLoader> clf) {
482 for (ResolvedModule resolvedModule : cf.modules()) {
483 ModuleReference mref = resolvedModule.reference();
484 String name = resolvedModule.name();
485 ClassLoader loader = clf.apply(name);
486 if (loader == null) {
487 // skip java.base as it is already loaded
488 if (!name.equals(JAVA_BASE)) {
489 BootLoader.loadModule(mref);
490 }
491 } else if (loader instanceof BuiltinClassLoader) {
492 ((BuiltinClassLoader) loader).loadModule(mref);
1032 if (nameToModule == null) {
1033 this.nameToModule = nameToModule = mrefs.stream()
1034 .collect(Collectors.toMap(m -> m.descriptor().name(),
1035 Function.identity()));
1036 }
1037 return Optional.ofNullable(nameToModule.get(name));
1038 }
1039 @Override
1040 public Set<ModuleReference> findAll() {
1041 return mrefs;
1042 }
1043 }
1044
1045 /**
1046 * Counters for startup performance analysis.
1047 */
1048 static class Counters {
1049 private static final boolean PUBLISH_COUNTERS;
1050 private static final boolean PRINT_COUNTERS;
1051 private static Map<String, Long> counters;
1052 static {
1053 String s = System.getProperty("jdk.module.boot.usePerfData");
1054 if (s == null) {
1055 PUBLISH_COUNTERS = false;
1056 PRINT_COUNTERS = false;
1057 } else {
1058 PUBLISH_COUNTERS = true;
1059 PRINT_COUNTERS = s.equals("debug");
1060 counters = new LinkedHashMap<>(); // preserve insert order
1061 }
1062 }
1063
1064 /**
1065 * Add a counter
1066 */
1067 static void add(String name, long start) {
1068 if (PUBLISH_COUNTERS || PRINT_COUNTERS) {
1069 counters.put(name, (System.nanoTime() - start));
1070 }
1071 }
1072
1073 /**
1074 * Publish the counters to the instrumentation buffer or stdout.
1075 */
1076 static void publish() {
1077 if (PUBLISH_COUNTERS || PRINT_COUNTERS) {
1078 for (Map.Entry<String, Long> e : counters.entrySet()) {
1079 String name = e.getKey();
1080 long value = e.getValue();
1081 if (PUBLISH_COUNTERS)
1082 PerfCounter.newPerfCounter(name).set(value);
1083 if (PRINT_COUNTERS)
1084 System.out.println(name + " = " + value);
1085 }
1086 }
1087 }
1088 }
1089 }
|
1 /*
2 * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
123 * Returns the ModuleFinder for the initial configuration.
124 *
125 * @apiNote Used to support "{@code java --list-modules}".
126 */
127 public static ModuleFinder limitedFinder() {
128 ModuleFinder finder = limitedFinder;
129 if (finder == null) {
130 return unlimitedFinder();
131 } else {
132 return finder;
133 }
134 }
135
136 /**
137 * Initialize the module system, returning the boot layer.
138 *
139 * @see java.lang.System#initPhase2(boolean, boolean)
140 */
141 public static ModuleLayer boot() throws Exception {
142
143 Counters.start();
144
145 // Step 0: Command line options
146
147 ModuleFinder upgradeModulePath = finderFor("jdk.module.upgrade.path");
148 ModuleFinder appModulePath = finderFor("jdk.module.path");
149 boolean isPatched = patcher.hasPatches();
150
151 String mainModule = System.getProperty("jdk.module.main");
152 Set<String> addModules = addModules();
153 Set<String> limitModules = limitModules();
154
155 PrintStream traceOutput = null;
156 String trace = getAndRemoveProperty("jdk.module.showModuleResolution");
157 if (trace != null && Boolean.parseBoolean(trace))
158 traceOutput = System.out;
159
160 Counters.add("jdk.module.boot.0.commandLineTime");
161
162 // Step 1: The observable system modules, either all system modules
163 // or the system modules pre-generated for the initial module (the
164 // initial module may be the unnamed module). If the system modules
165 // are pre-generated for the initial module then resolution can be
166 // skipped.
167
168 SystemModules systemModules = null;
169 ModuleFinder systemModuleFinder;
170
171 boolean haveModulePath = (appModulePath != null || upgradeModulePath != null);
172 boolean needResolution = true;
173 boolean canArchive = false;
174 boolean hasSplitPackages;
175 boolean hasIncubatorModules;
176
177 // If the java heap was archived at CDS dump time and the environment
178 // at dump time matches the current environment then use the archived
179 // system modules and finder.
180 ArchivedModuleGraph archivedModuleGraph = ArchivedModuleGraph.get(mainModule);
181 if (archivedModuleGraph != null
182 && !haveModulePath
183 && addModules.isEmpty()
184 && limitModules.isEmpty()
185 && !isPatched) {
186 systemModuleFinder = archivedModuleGraph.finder();
187 hasSplitPackages = archivedModuleGraph.hasSplitPackages();
197 }
198 if (systemModules == null) {
199 // all system modules are observable
200 systemModules = SystemModuleFinders.allSystemModules();
201 }
202 if (systemModules != null) {
203 // images build
204 systemModuleFinder = SystemModuleFinders.of(systemModules);
205 } else {
206 // exploded build or testing
207 systemModules = new ExplodedSystemModules();
208 systemModuleFinder = SystemModuleFinders.ofSystem();
209 }
210
211 hasSplitPackages = systemModules.hasSplitPackages();
212 hasIncubatorModules = systemModules.hasIncubatorModules();
213 // not using the archived module graph - avoid accidental use
214 archivedModuleGraph = null;
215 }
216
217 Counters.add("jdk.module.boot.1.systemModulesTime");
218
219 // Step 2: Define and load java.base. This patches all classes loaded
220 // to date so that they are members of java.base. Once java.base is
221 // loaded then resources in java.base are available for error messages
222 // needed from here on.
223
224 ModuleReference base = systemModuleFinder.find(JAVA_BASE).orElse(null);
225 if (base == null)
226 throw new InternalError(JAVA_BASE + " not found");
227 URI baseUri = base.location().orElse(null);
228 if (baseUri == null)
229 throw new InternalError(JAVA_BASE + " does not have a location");
230 BootLoader.loadModule(base);
231 Modules.defineModule(null, base.descriptor(), baseUri);
232
233 // Step 2a: Scan all modules when --validate-modules specified
234
235 if (getAndRemoveProperty("jdk.module.validation") != null) {
236 int errors = ModulePathValidator.scanAllModules(System.out);
237 if (errors > 0) {
238 fail("Validation of module path failed");
239 }
240 }
241
242 Counters.add("jdk.module.boot.2.defineBaseTime");
243
244 // Step 3: If resolution is needed then create the module finder and
245 // the set of root modules to resolve.
246
247 ModuleFinder savedModuleFinder = null;
248 ModuleFinder finder;
249 Set<String> roots;
250 if (needResolution) {
251
252 // upgraded modules override the modules in the run-time image
253 if (upgradeModulePath != null)
254 systemModuleFinder = ModuleFinder.compose(upgradeModulePath,
255 systemModuleFinder);
256
257 // The module finder: [--upgrade-module-path] system [--module-path]
258 if (appModulePath != null) {
259 finder = ModuleFinder.compose(systemModuleFinder, appModulePath);
260 } else {
261 finder = systemModuleFinder;
262 }
263
264 // The root modules to resolve
265 roots = new HashSet<>();
266
316 .forEach(mn -> roots.add(mn));
317 }
318
319 // If `--add-modules ALL-MODULE-PATH` is specified then all observable
320 // modules on the application module path will be resolved.
321 if (appModulePath != null && addAllApplicationModules) {
322 ModuleFinder f = finder; // observable modules
323 appModulePath.findAll()
324 .stream()
325 .map(ModuleReference::descriptor)
326 .map(ModuleDescriptor::name)
327 .filter(mn -> f.find(mn).isPresent()) // observable
328 .forEach(mn -> roots.add(mn));
329 }
330 } else {
331 // no resolution case
332 finder = systemModuleFinder;
333 roots = null;
334 }
335
336 Counters.add("jdk.module.boot.3.optionsAndRootsTime");
337
338 // Step 4: Resolve the root modules, with service binding, to create
339 // the configuration for the boot layer. If resolution is not needed
340 // then create the configuration for the boot layer from the
341 // readability graph created at link time.
342
343 Configuration cf;
344 if (needResolution) {
345 cf = Modules.newBootLayerConfiguration(finder, roots, traceOutput);
346 } else {
347 if (archivedModuleGraph != null) {
348 cf = archivedModuleGraph.configuration();
349 } else {
350 Map<String, Set<String>> map = systemModules.moduleReads();
351 cf = JLMA.newConfiguration(systemModuleFinder, map);
352 }
353 }
354
355 // check that modules specified to --patch-module are resolved
356 if (isPatched) {
357 patcher.patchedModules()
358 .stream()
359 .filter(mn -> !cf.findModule(mn).isPresent())
360 .forEach(mn -> warnUnknownModule(PATCH_MODULE, mn));
361 }
362
363 Counters.add("jdk.module.boot.4.resolveTime");
364
365 // Step 5: Map the modules in the configuration to class loaders.
366 // The static configuration provides the mapping of standard and JDK
367 // modules to the boot and platform loaders. All other modules (JDK
368 // tool modules, and both explicit and automatic modules on the
369 // application module path) are defined to the application class
370 // loader.
371
372 // mapping of modules to class loaders
373 Function<String, ClassLoader> clf = ModuleLoaderMap.mappingFunction(cf);
374
375 // check that all modules to be mapped to the boot loader will be
376 // loaded from the runtime image
377 if (haveModulePath) {
378 for (ResolvedModule resolvedModule : cf.modules()) {
379 ModuleReference mref = resolvedModule.reference();
380 String name = mref.descriptor().name();
381 ClassLoader cl = clf.apply(name);
382 if (cl == null) {
383 if (upgradeModulePath != null
384 && upgradeModulePath.find(name).isPresent())
385 fail(name + ": cannot be loaded from upgrade module path");
386 if (!systemModuleFinder.find(name).isPresent())
387 fail(name + ": cannot be loaded from application module path");
388 }
389 }
390 }
391
392 // check for split packages in the modules mapped to the built-in loaders
393 if (hasSplitPackages || isPatched || haveModulePath) {
394 checkSplitPackages(cf, clf);
395 }
396
397 // load/register the modules with the built-in class loaders
398 loadModules(cf, clf);
399 Counters.add("jdk.module.boot.5.loadModulesTime");
400
401 // Step 6: Define all modules to the VM
402
403 ModuleLayer bootLayer = ModuleLayer.empty().defineModules(cf, clf);
404 Counters.add("jdk.module.boot.6.layerCreateTime");
405
406 // Step 7: Miscellaneous
407
408 // check incubating status
409 if (hasIncubatorModules || haveModulePath) {
410 checkIncubatingStatus(cf);
411 }
412
413 // --add-reads, --add-exports/--add-opens, and --illegal-access
414 addExtraReads(bootLayer);
415 boolean extraExportsOrOpens = addExtraExportsAndOpens(bootLayer);
416
417 Map<String, Set<String>> concealedPackagesToOpen;
418 Map<String, Set<String>> exportedPackagesToOpen;
419 if (archivedModuleGraph != null) {
420 concealedPackagesToOpen = archivedModuleGraph.concealedPackagesToOpen();
421 exportedPackagesToOpen = archivedModuleGraph.exportedPackagesToOpen();
422 } else {
423 concealedPackagesToOpen = systemModules.concealedPackagesToOpen();
424 exportedPackagesToOpen = systemModules.exportedPackagesToOpen();
425 }
426 addIllegalAccess(upgradeModulePath,
427 concealedPackagesToOpen,
428 exportedPackagesToOpen,
429 bootLayer,
430 extraExportsOrOpens);
431 Counters.add("jdk.module.boot.7.adjustModulesTime");
432
433 // save module finders for later use
434 if (savedModuleFinder != null) {
435 unlimitedFinder = new SafeModuleFinder(savedModuleFinder);
436 if (savedModuleFinder != finder)
437 limitedFinder = new SafeModuleFinder(finder);
438 }
439
440 // Module graph can be archived at CDS dump time. Only allow the
441 // unnamed module case for now.
442 if (canArchive && (mainModule == null)) {
443 ArchivedModuleGraph.archive(mainModule,
444 hasSplitPackages,
445 hasIncubatorModules,
446 systemModuleFinder,
447 cf,
448 concealedPackagesToOpen,
449 exportedPackagesToOpen);
450 }
451
452 // total time to initialize
453 Counters.publish("jdk.module.boot.totalTime");
454
455 return bootLayer;
456 }
457
458 /**
459 * Load/register the modules to the built-in class loaders.
460 */
461 private static void loadModules(Configuration cf,
462 Function<String, ClassLoader> clf) {
463 for (ResolvedModule resolvedModule : cf.modules()) {
464 ModuleReference mref = resolvedModule.reference();
465 String name = resolvedModule.name();
466 ClassLoader loader = clf.apply(name);
467 if (loader == null) {
468 // skip java.base as it is already loaded
469 if (!name.equals(JAVA_BASE)) {
470 BootLoader.loadModule(mref);
471 }
472 } else if (loader instanceof BuiltinClassLoader) {
473 ((BuiltinClassLoader) loader).loadModule(mref);
1013 if (nameToModule == null) {
1014 this.nameToModule = nameToModule = mrefs.stream()
1015 .collect(Collectors.toMap(m -> m.descriptor().name(),
1016 Function.identity()));
1017 }
1018 return Optional.ofNullable(nameToModule.get(name));
1019 }
1020 @Override
1021 public Set<ModuleReference> findAll() {
1022 return mrefs;
1023 }
1024 }
1025
1026 /**
1027 * Counters for startup performance analysis.
1028 */
1029 static class Counters {
1030 private static final boolean PUBLISH_COUNTERS;
1031 private static final boolean PRINT_COUNTERS;
1032 private static Map<String, Long> counters;
1033 private static long startTime;
1034 private static long previousTime;
1035
1036 static {
1037 String s = System.getProperty("jdk.module.boot.usePerfData");
1038 if (s == null) {
1039 PUBLISH_COUNTERS = false;
1040 PRINT_COUNTERS = false;
1041 } else {
1042 PUBLISH_COUNTERS = true;
1043 PRINT_COUNTERS = s.equals("debug");
1044 counters = new LinkedHashMap<>(); // preserve insert order
1045 }
1046 }
1047
1048 /**
1049 * Start counting time.
1050 */
1051 static void start() {
1052 if (PUBLISH_COUNTERS) {
1053 startTime = previousTime = System.nanoTime();
1054 }
1055 }
1056
1057 /**
1058 * Add a counter - storing the time difference between now and the
1059 * previous add or the start.
1060 */
1061 static void add(String name) {
1062 if (PUBLISH_COUNTERS) {
1063 long current = System.nanoTime();
1064 long elapsed = current - previousTime;
1065 previousTime = current;
1066 counters.put(name, elapsed);
1067 }
1068 }
1069
1070 /**
1071 * Publish the counters to the instrumentation buffer or stdout.
1072 */
1073 static void publish(String totalTimeName) {
1074 if (PUBLISH_COUNTERS) {
1075 long currentTime = System.nanoTime();
1076 for (Map.Entry<String, Long> e : counters.entrySet()) {
1077 String name = e.getKey();
1078 long value = e.getValue();
1079 PerfCounter.newPerfCounter(name).set(value);
1080 if (PRINT_COUNTERS)
1081 System.out.println(name + " = " + value);
1082 }
1083 long elapsedTotal = currentTime - startTime;
1084 PerfCounter.newPerfCounter(totalTimeName).set(elapsedTotal);
1085 if (PRINT_COUNTERS)
1086 System.out.println(totalTimeName + " = " + elapsedTotal);
1087 }
1088 }
1089 }
1090 }
|