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
176 // If the java heap was archived at CDS dump time and the environment
177 // at dump time matches the current environment then use the archived
178 // system modules and finder.
179 ArchivedModuleGraph archivedModuleGraph = ArchivedModuleGraph.get(mainModule);
180 if (archivedModuleGraph != null
181 && !haveModulePath
182 && addModules.isEmpty()
183 && limitModules.isEmpty()
184 && !isPatched) {
185 systemModules = archivedModuleGraph.systemModules();
186 systemModuleFinder = archivedModuleGraph.finder();
187 needResolution = (traceOutput != null);
188 } else {
189 if (!haveModulePath && addModules.isEmpty() && limitModules.isEmpty()) {
190 systemModules = SystemModuleFinders.systemModules(mainModule);
191 if (systemModules != null && !isPatched) {
192 needResolution = (traceOutput != null);
193 canArchive = true;
194 }
195 }
196 if (systemModules == null) {
197 // all system modules are observable
198 systemModules = SystemModuleFinders.allSystemModules();
199 }
200 if (systemModules != null) {
201 // images build
202 systemModuleFinder = SystemModuleFinders.of(systemModules);
203 } else {
204 // exploded build or testing
205 systemModules = new ExplodedSystemModules();
206 systemModuleFinder = SystemModuleFinders.ofSystem();
207 }
208 }
209
210 Counters.add("jdk.module.boot.1.systemModulesTime", t1);
211
212
213 // Step 2: Define and load java.base. This patches all classes loaded
214 // to date so that they are members of java.base. Once java.base is
215 // loaded then resources in java.base are available for error messages
216 // needed from here on.
217
218 long t2 = System.nanoTime();
219
220 ModuleReference base = systemModuleFinder.find(JAVA_BASE).orElse(null);
221 if (base == null)
222 throw new InternalError(JAVA_BASE + " not found");
223 URI baseUri = base.location().orElse(null);
224 if (baseUri == null)
225 throw new InternalError(JAVA_BASE + " does not have a location");
226 BootLoader.loadModule(base);
227 Modules.defineModule(null, base.descriptor(), baseUri);
378 Function<String, ClassLoader> clf = ModuleLoaderMap.mappingFunction(cf);
379
380 // check that all modules to be mapped to the boot loader will be
381 // loaded from the runtime image
382 if (haveModulePath) {
383 for (ResolvedModule resolvedModule : cf.modules()) {
384 ModuleReference mref = resolvedModule.reference();
385 String name = mref.descriptor().name();
386 ClassLoader cl = clf.apply(name);
387 if (cl == null) {
388 if (upgradeModulePath != null
389 && upgradeModulePath.find(name).isPresent())
390 fail(name + ": cannot be loaded from upgrade module path");
391 if (!systemModuleFinder.find(name).isPresent())
392 fail(name + ": cannot be loaded from application module path");
393 }
394 }
395 }
396
397 // check for split packages in the modules mapped to the built-in loaders
398 if (systemModules.hasSplitPackages() || isPatched || haveModulePath) {
399 checkSplitPackages(cf, clf);
400 }
401
402 // load/register the modules with the built-in class loaders
403 loadModules(cf, clf);
404
405 Counters.add("jdk.module.boot.5.loadModulesTime", t5);
406
407
408 // Step 6: Define all modules to the VM
409
410 long t6 = System.nanoTime();
411 ModuleLayer bootLayer = ModuleLayer.empty().defineModules(cf, clf);
412 Counters.add("jdk.module.boot.6.layerCreateTime", t6);
413
414
415 // Step 7: Miscellaneous
416
417 // check incubating status
418 if (systemModules.hasIncubatorModules() || haveModulePath) {
419 checkIncubatingStatus(cf);
420 }
421
422 // --add-reads, --add-exports/--add-opens, and --illegal-access
423 long t7 = System.nanoTime();
424 addExtraReads(bootLayer);
425 boolean extraExportsOrOpens = addExtraExportsAndOpens(bootLayer);
426 addIllegalAccess(upgradeModulePath, systemModules, bootLayer, extraExportsOrOpens);
427 Counters.add("jdk.module.boot.7.adjustModulesTime", t7);
428
429 // save module finders for later use
430 if (savedModuleFinder != null) {
431 unlimitedFinder = new SafeModuleFinder(savedModuleFinder);
432 if (savedModuleFinder != finder)
433 limitedFinder = new SafeModuleFinder(finder);
434 }
435
436 // Module graph can be archived at CDS dump time. Only allow the
437 // unnamed module case for now.
438 if (canArchive && (mainModule == null)) {
439 ArchivedModuleGraph.archive(mainModule, systemModules,
440 systemModuleFinder, cf);
441 }
442
443 // total time to initialize
444 Counters.add("jdk.module.boot.totalTime", t0);
445 Counters.publish();
446
447 return bootLayer;
448 }
449
450 /**
451 * Load/register the modules to the built-in class loaders.
452 */
453 private static void loadModules(Configuration cf,
454 Function<String, ClassLoader> clf) {
455 for (ResolvedModule resolvedModule : cf.modules()) {
456 ModuleReference mref = resolvedModule.reference();
457 String name = resolvedModule.name();
458 ClassLoader loader = clf.apply(name);
459 if (loader == null) {
460 // skip java.base as it is already loaded
721 } else {
722 Modules.addExportsToAllUnnamed(m, pn);
723 }
724 } else {
725 if (opens) {
726 Modules.addOpens(m, pn, other);
727 } else {
728 Modules.addExports(m, pn, other);
729 }
730 }
731
732 }
733 }
734 }
735
736 /**
737 * Process the --illegal-access option (and its default) to open packages
738 * of system modules in the boot layer to code in unnamed modules.
739 */
740 private static void addIllegalAccess(ModuleFinder upgradeModulePath,
741 SystemModules systemModules,
742 ModuleLayer bootLayer,
743 boolean extraExportsOrOpens) {
744 String value = getAndRemoveProperty("jdk.module.illegalAccess");
745 IllegalAccessLogger.Mode mode = IllegalAccessLogger.Mode.ONESHOT;
746 if (value != null) {
747 switch (value) {
748 case "deny":
749 return;
750 case "permit":
751 break;
752 case "warn":
753 mode = IllegalAccessLogger.Mode.WARN;
754 break;
755 case "debug":
756 mode = IllegalAccessLogger.Mode.DEBUG;
757 break;
758 default:
759 fail("Value specified to --illegal-access not recognized:"
760 + " '" + value + "'");
761 return;
762 }
763 }
764 IllegalAccessLogger.Builder builder
765 = new IllegalAccessLogger.Builder(mode, System.err);
766
767 Map<String, Set<String>> map1 = systemModules.concealedPackagesToOpen();
768 Map<String, Set<String>> map2 = systemModules.exportedPackagesToOpen();
769 if (map1.isEmpty() && map2.isEmpty()) {
770 // need to generate (exploded build)
771 IllegalAccessMaps maps = IllegalAccessMaps.generate(limitedFinder());
772 map1 = maps.concealedPackagesToOpen();
773 map2 = maps.exportedPackagesToOpen();
774 }
775
776 // open specific packages in the system modules
777 for (Module m : bootLayer.modules()) {
778 ModuleDescriptor descriptor = m.getDescriptor();
779 String name = m.getName();
780
781 // skip open modules
782 if (descriptor.isOpen()) {
783 continue;
784 }
785
786 // skip modules loaded from the upgrade module path
787 if (upgradeModulePath != null
788 && upgradeModulePath.find(name).isPresent()) {
789 continue;
790 }
791
792 Set<String> concealedPackages = map1.getOrDefault(name, Set.of());
793 Set<String> exportedPackages = map2.getOrDefault(name, Set.of());
794
795 // refresh the set of concealed and exported packages if needed
796 if (extraExportsOrOpens) {
797 concealedPackages = new HashSet<>(concealedPackages);
798 exportedPackages = new HashSet<>(exportedPackages);
799 Iterator<String> iterator = concealedPackages.iterator();
800 while (iterator.hasNext()) {
801 String pn = iterator.next();
802 if (m.isExported(pn, BootLoader.getUnnamedModule())) {
803 // concealed package is exported to ALL-UNNAMED
804 iterator.remove();
805 exportedPackages.add(pn);
806 }
807 }
808 iterator = exportedPackages.iterator();
809 while (iterator.hasNext()) {
810 String pn = iterator.next();
811 if (m.isOpen(pn, BootLoader.getUnnamedModule())) {
812 // exported package is opened to ALL-UNNAMED
813 iterator.remove();
|
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();
189 hasIncubatorModules = archivedModuleGraph.hasIncubatorModules();
190 needResolution = (traceOutput != null);
191 } else {
192 if (!haveModulePath && addModules.isEmpty() && limitModules.isEmpty()) {
193 systemModules = SystemModuleFinders.systemModules(mainModule);
194 if (systemModules != null && !isPatched) {
195 needResolution = (traceOutput != null);
196 canArchive = true;
197 }
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);
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
748 } else {
749 Modules.addExportsToAllUnnamed(m, pn);
750 }
751 } else {
752 if (opens) {
753 Modules.addOpens(m, pn, other);
754 } else {
755 Modules.addExports(m, pn, other);
756 }
757 }
758
759 }
760 }
761 }
762
763 /**
764 * Process the --illegal-access option (and its default) to open packages
765 * of system modules in the boot layer to code in unnamed modules.
766 */
767 private static void addIllegalAccess(ModuleFinder upgradeModulePath,
768 Map<String, Set<String>> concealedPackagesToOpen,
769 Map<String, Set<String>> exportedPackagesToOpen,
770 ModuleLayer bootLayer,
771 boolean extraExportsOrOpens) {
772 String value = getAndRemoveProperty("jdk.module.illegalAccess");
773 IllegalAccessLogger.Mode mode = IllegalAccessLogger.Mode.ONESHOT;
774 if (value != null) {
775 switch (value) {
776 case "deny":
777 return;
778 case "permit":
779 break;
780 case "warn":
781 mode = IllegalAccessLogger.Mode.WARN;
782 break;
783 case "debug":
784 mode = IllegalAccessLogger.Mode.DEBUG;
785 break;
786 default:
787 fail("Value specified to --illegal-access not recognized:"
788 + " '" + value + "'");
789 return;
790 }
791 }
792 IllegalAccessLogger.Builder builder
793 = new IllegalAccessLogger.Builder(mode, System.err);
794
795 if (concealedPackagesToOpen.isEmpty() && exportedPackagesToOpen.isEmpty()) {
796 // need to generate (exploded build)
797 IllegalAccessMaps maps = IllegalAccessMaps.generate(limitedFinder());
798 concealedPackagesToOpen = maps.concealedPackagesToOpen();
799 exportedPackagesToOpen = maps.exportedPackagesToOpen();
800 }
801
802 // open specific packages in the system modules
803 for (Module m : bootLayer.modules()) {
804 ModuleDescriptor descriptor = m.getDescriptor();
805 String name = m.getName();
806
807 // skip open modules
808 if (descriptor.isOpen()) {
809 continue;
810 }
811
812 // skip modules loaded from the upgrade module path
813 if (upgradeModulePath != null
814 && upgradeModulePath.find(name).isPresent()) {
815 continue;
816 }
817
818 Set<String> concealedPackages = concealedPackagesToOpen.getOrDefault(name, Set.of());
819 Set<String> exportedPackages = exportedPackagesToOpen.getOrDefault(name, Set.of());
820
821 // refresh the set of concealed and exported packages if needed
822 if (extraExportsOrOpens) {
823 concealedPackages = new HashSet<>(concealedPackages);
824 exportedPackages = new HashSet<>(exportedPackages);
825 Iterator<String> iterator = concealedPackages.iterator();
826 while (iterator.hasNext()) {
827 String pn = iterator.next();
828 if (m.isExported(pn, BootLoader.getUnnamedModule())) {
829 // concealed package is exported to ALL-UNNAMED
830 iterator.remove();
831 exportedPackages.add(pn);
832 }
833 }
834 iterator = exportedPackages.iterator();
835 while (iterator.hasNext()) {
836 String pn = iterator.next();
837 if (m.isOpen(pn, BootLoader.getUnnamedModule())) {
838 // exported package is opened to ALL-UNNAMED
839 iterator.remove();
|