25
26 package jdk.internal.module;
27
28 import java.io.File;
29 import java.io.PrintStream;
30 import java.lang.module.Configuration;
31 import java.lang.module.ModuleDescriptor;
32 import java.lang.module.ModuleFinder;
33 import java.lang.module.ModuleReference;
34 import java.lang.module.ResolvedModule;
35 import java.net.URI;
36 import java.nio.file.Path;
37 import java.util.ArrayList;
38 import java.util.Collections;
39 import java.util.HashMap;
40 import java.util.HashSet;
41 import java.util.Iterator;
42 import java.util.LinkedHashMap;
43 import java.util.List;
44 import java.util.Map;
45 import java.util.NoSuchElementException;
46 import java.util.Objects;
47 import java.util.Optional;
48 import java.util.Set;
49 import java.util.function.Function;
50 import java.util.stream.Collectors;
51
52 import jdk.internal.loader.BootLoader;
53 import jdk.internal.loader.BuiltinClassLoader;
54 import jdk.internal.loader.ClassLoaders;
55 import jdk.internal.misc.VM;
56 import jdk.internal.access.JavaLangAccess;
57 import jdk.internal.access.JavaLangModuleAccess;
58 import jdk.internal.access.SharedSecrets;
59 import jdk.internal.perf.PerfCounter;
60
61 /**
62 * Initializes/boots the module system.
63 *
64 * The {@link #boot() boot} method is called early in the startup to initialize
65 * the module system. In summary, the boot method creates a Configuration by
66 * resolving a set of module names specified via the launcher (or equivalent)
67 * -m and --add-modules options. The modules are located on a module path that
68 * is constructed from the upgrade module path, system modules, and application
69 * module path. The Configuration is instantiated as the boot layer with each
70 * module in the configuration defined to a class loader.
71 */
72
73 public final class ModuleBootstrap {
74 private ModuleBootstrap() { }
75
76 private static final String JAVA_BASE = "java.base";
77
78 // the token for "all default modules"
79 private static final String ALL_DEFAULT = "ALL-DEFAULT";
80
81 // the token for "all unnamed modules"
82 private static final String ALL_UNNAMED = "ALL-UNNAMED";
83
84 // the token for "all system modules"
85 private static final String ALL_SYSTEM = "ALL-SYSTEM";
86
87 // the token for "all modules on the module path"
88 private static final String ALL_MODULE_PATH = "ALL-MODULE-PATH";
89
90 // access to java.lang/module
91 private static final JavaLangModuleAccess JLMA
92 = SharedSecrets.getJavaLangModuleAccess();
93
94 // The ModulePatcher for the initial configuration
95 private static final ModulePatcher patcher = initModulePatcher();
96
97 /**
98 * Returns the ModulePatcher for the initial configuration.
99 */
100 public static ModulePatcher patcher() {
101 return patcher;
102 }
103
104 // ModuleFinders for the initial configuration
105 private static volatile ModuleFinder unlimitedFinder;
106 private static volatile ModuleFinder limitedFinder;
107
108 /**
109 * Returns the ModuleFinder for the initial configuration before
110 * observability is limited by the --limit-modules command line option.
111 *
112 * @apiNote Used to support locating modules {@code java.instrument} and
118 return ModuleFinder.ofSystem();
119 } else {
120 return finder;
121 }
122 }
123
124 /**
125 * Returns the ModuleFinder for the initial configuration.
126 *
127 * @apiNote Used to support "{@code java --list-modules}".
128 */
129 public static ModuleFinder limitedFinder() {
130 ModuleFinder finder = limitedFinder;
131 if (finder == null) {
132 return unlimitedFinder();
133 } else {
134 return finder;
135 }
136 }
137
138 private static class ArchivedBootLayer {
139 private static ArchivedBootLayer archivedBootLayer;
140
141 private final ModuleLayer bootLayer;
142 private final ModuleFinder limitedFinder;
143 private final IllegalAccessLogger.Builder builder;
144 private final ModuleFinder unlimitedFinder;
145 private final ServicesCatalog platformCatalog;
146 private final ServicesCatalog appCatalog;
147
148 public ArchivedBootLayer(ModuleLayer bootLayer,
149 ModuleFinder limitedFinder,
150 ModuleFinder unlimitedFinder,
151 IllegalAccessLogger.Builder builder) {
152 this.bootLayer = bootLayer;
153 this.limitedFinder = limitedFinder;
154 this.unlimitedFinder = unlimitedFinder;
155 this.builder = builder;
156
157 this.platformCatalog = ServicesCatalog.getServicesCatalog(ClassLoaders.platformClassLoader());
158 this.appCatalog = ServicesCatalog.getServicesCatalog(ClassLoaders.appClassLoader());
159 }
160
161 static ArchivedBootLayer get() {
162 // The VM will initialize archivedBootLayer only if MetaspaceShared::use_full_module_graph() is true.
163 return archivedBootLayer;
164 }
165
166 static void archive(ArchivedBootLayer layer) {
167 archivedBootLayer = layer;
168 }
169
170 static {
171 VM.initializeFromArchive(ArchivedBootLayer.class);
172 }
173 }
174
175 private static boolean hasProperty(String key) {
176 return System.getProperty(key) != null;
177 }
178
179 private static boolean mayUseArchivedBootLayer() {
180 // If these properties are set, we cannot use the archived boot layer.
181 // The VM should have already checked this before initializing
182 // ArchivedBootLayer::archivedBootLayer.
183 if (hasProperty("jdk.module.upgrade.path") ||
184 hasProperty("jdk.module.main") ||
185 hasProperty("jdk.module.limitmods") ||
186 hasProperty("jdk.module.validation") ||
187 hasProperty("jdk.module.showModuleResolution") ||
188 hasProperty("jdk.module.illegalAccess") ||
189 hasProperty("java.system.class.loader") ||
190 hasProperty("jdk.module.addexports.0") ||
191 hasProperty("jdk.module.addopens.0") ||
192 hasProperty("jdk.module.addreads.0") ||
193 hasProperty("jdk.module.patch.0") ||
194 hasProperty("jdk.module.addmods.0")) {
195 return false;
196 } else {
197 return true;
198 }
199 }
200
201 private static ModuleLayer getArchivedBootLayer() {
202 ArchivedBootLayer archivedBootLayer = ArchivedBootLayer.get();
203 if (archivedBootLayer != null) {
204 assert mayUseArchivedBootLayer();
205 Counters.add("jdk.module.boot.0.archivedBootLayer");
206 limitedFinder = archivedBootLayer.limitedFinder;
207 unlimitedFinder = archivedBootLayer.unlimitedFinder;
208 ModuleLayer bootLayer = archivedBootLayer.bootLayer;
209
210 // Trigger BootLoader.<clinit>
211 BootLoader.getUnnamedModule();
212
213 // BootLoader.SERVICES_CATALOG is saved/restored separately in BootLoader.java
214 ServicesCatalog.setServicesCatalog(ClassLoaders.platformClassLoader(),
215 archivedBootLayer.platformCatalog);
216 ServicesCatalog.setServicesCatalog(ClassLoaders.appClassLoader(),
217 archivedBootLayer.appCatalog);
218
219 JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
220 jla.bindToLoader(bootLayer, ClassLoaders.appClassLoader());
221
222 IllegalAccessLogger.Builder builder = archivedBootLayer.builder;
223 if (builder != null) {
224 builder.complete();
225 }
226
227 Counters.publish("jdk.module.boot.totalTime");
228 return bootLayer;
229 }
230
231 return null;
232 }
233
234
235 /**
236 * Initialize the module system, returning the boot layer.
237 *
238 * @see java.lang.System#initPhase2(boolean, boolean)
239 */
240 public static ModuleLayer boot() throws Exception {
241
242 Counters.start();
243 ModuleLayer bootLayer = getArchivedBootLayer();
244 if (bootLayer != null) {
245 return bootLayer;
246 }
247
248 // Step 0: Command line options
249
250 ModuleFinder upgradeModulePath = finderFor("jdk.module.upgrade.path");
251 ModuleFinder appModulePath = finderFor("jdk.module.path");
252 boolean isPatched = patcher.hasPatches();
253
254 String mainModule = System.getProperty("jdk.module.main");
255 Set<String> addModules = addModules();
256 Set<String> limitModules = limitModules();
257
258 PrintStream traceOutput = null;
259 String trace = getAndRemoveProperty("jdk.module.showModuleResolution");
260 if (trace != null && Boolean.parseBoolean(trace))
261 traceOutput = System.out;
262
263 Counters.add("jdk.module.boot.0.commandLineTime");
264
265 // Step 1: The observable system modules, either all system modules
266 // or the system modules pre-generated for the initial module (the
267 // initial module may be the unnamed module). If the system modules
491 if (upgradeModulePath != null
492 && upgradeModulePath.find(name).isPresent())
493 fail(name + ": cannot be loaded from upgrade module path");
494 if (!systemModuleFinder.find(name).isPresent())
495 fail(name + ": cannot be loaded from application module path");
496 }
497 }
498 }
499
500 // check for split packages in the modules mapped to the built-in loaders
501 if (hasSplitPackages || isPatched || haveModulePath) {
502 checkSplitPackages(cf, clf);
503 }
504
505 // load/register the modules with the built-in class loaders
506 loadModules(cf, clf);
507 Counters.add("jdk.module.boot.5.loadModulesTime");
508
509 // Step 6: Define all modules to the VM
510
511 bootLayer = ModuleLayer.empty().defineModules(cf, clf);
512 Counters.add("jdk.module.boot.6.layerCreateTime");
513
514 // Step 7: Miscellaneous
515
516 // check incubating status
517 if (hasIncubatorModules || haveModulePath) {
518 checkIncubatingStatus(cf);
519 }
520
521 // --add-reads, --add-exports/--add-opens, and --illegal-access
522 addExtraReads(bootLayer);
523 boolean extraExportsOrOpens = addExtraExportsAndOpens(bootLayer);
524
525 Map<String, Set<String>> concealedPackagesToOpen;
526 Map<String, Set<String>> exportedPackagesToOpen;
527 if (archivedModuleGraph != null) {
528 concealedPackagesToOpen = archivedModuleGraph.concealedPackagesToOpen();
529 exportedPackagesToOpen = archivedModuleGraph.exportedPackagesToOpen();
530 } else {
531 concealedPackagesToOpen = systemModules.concealedPackagesToOpen();
532 exportedPackagesToOpen = systemModules.exportedPackagesToOpen();
533 }
534 IllegalAccessLogger.Builder builder =
535 addIllegalAccess(upgradeModulePath,
536 concealedPackagesToOpen,
537 exportedPackagesToOpen,
538 bootLayer,
539 extraExportsOrOpens);
540 Counters.add("jdk.module.boot.7.adjustModulesTime");
541
542 // save module finders for later use
543 if (savedModuleFinder != null) {
544 unlimitedFinder = new SafeModuleFinder(savedModuleFinder);
545 if (savedModuleFinder != finder)
546 limitedFinder = new SafeModuleFinder(finder);
547 }
548
549 // Module graph can be archived at CDS dump time. Only allow the
550 // unnamed module case for now.
551 if (canArchive && (mainModule == null)) {
552 ArchivedModuleGraph.archive(
553 new ArchivedModuleGraph(hasSplitPackages,
554 hasIncubatorModules,
555 systemModuleFinder,
556 cf,
557 clf,
558 concealedPackagesToOpen,
559 exportedPackagesToOpen));
560 ArchivedBootLayer.archive(
561 new ArchivedBootLayer(bootLayer,
562 limitedFinder,
563 unlimitedFinder,
564 builder));
565 }
566
567 // total time to initialize
568 Counters.publish("jdk.module.boot.totalTime");
569
570 return bootLayer;
571 }
572
573 /**
574 * Load/register the modules to the built-in class loaders.
575 */
576 private static void loadModules(Configuration cf,
577 Function<String, ClassLoader> clf) {
578 for (ResolvedModule resolvedModule : cf.modules()) {
579 ModuleReference mref = resolvedModule.reference();
580 String name = resolvedModule.name();
581 ClassLoader loader = clf.apply(name);
582 if (loader == null) {
583 // skip java.base as it is already loaded
584 if (!name.equals(JAVA_BASE)) {
585 BootLoader.loadModule(mref);
586 }
587 } else if (loader instanceof BuiltinClassLoader) {
588 ((BuiltinClassLoader) loader).loadModule(mref);
929 exportedPackages.add(pn);
930 }
931 }
932 iterator = exportedPackages.iterator();
933 while (iterator.hasNext()) {
934 String pn = iterator.next();
935 if (m.isOpen(pn, BootLoader.getUnnamedModule())) {
936 // exported package is opened to ALL-UNNAMED
937 iterator.remove();
938 }
939 }
940 }
941
942 // log reflective access to all types in concealed packages
943 builder.logAccessToConcealedPackages(m, concealedPackages);
944
945 // log reflective access to non-public members/types in exported packages
946 builder.logAccessToExportedPackages(m, exportedPackages);
947
948 // open the packages to unnamed modules
949 JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
950 jla.addOpensToAllUnnamed(m, concealedPackages, exportedPackages);
951 }
952
953 builder.complete();
954 return builder;
955 }
956
957 /**
958 * Decodes the values of --add-reads, -add-exports, --add-opens or
959 * --patch-modules options that are encoded in system properties.
960 *
961 * @param prefix the system property prefix
962 * @praam regex the regex for splitting the RHS of the option value
963 */
964 private static Map<String, List<String>> decode(String prefix,
965 String regex,
966 boolean allowDuplicates) {
967 int index = 0;
968 // the system property is removed after decoding
969 String value = getAndRemoveProperty(prefix + index);
970 if (value == null)
999 }
1000 }
1001 if (ntargets == 0)
1002 fail("Target must be specified: " + option(prefix) + " " + value);
1003
1004 index++;
1005 value = getAndRemoveProperty(prefix + index);
1006 }
1007
1008 return map;
1009 }
1010
1011 /**
1012 * Decodes the values of --add-reads, -add-exports or --add-opens
1013 * which use the "," to separate the RHS of the option value.
1014 */
1015 private static Map<String, List<String>> decode(String prefix) {
1016 return decode(prefix, ",", true);
1017 }
1018
1019 /**
1020 * Gets and remove the named system property
1021 */
1022 private static String getAndRemoveProperty(String key) {
1023 return (String)System.getProperties().remove(key);
1024 }
1025
1026 /**
1027 * Checks incubating status of modules in the configuration
1028 */
1029 private static void checkIncubatingStatus(Configuration cf) {
1030 String incubating = null;
1031 for (ResolvedModule resolvedModule : cf.modules()) {
1032 ModuleReference mref = resolvedModule.reference();
1033
1034 // emit warning if the WARN_INCUBATING module resolution bit set
1035 if (ModuleResolution.hasIncubatingWarning(mref)) {
1036 String mn = mref.descriptor().name();
1037 if (incubating == null) {
1038 incubating = mn;
1039 } else {
1040 incubating += ", " + mn;
1041 }
1042 }
1043 }
|
25
26 package jdk.internal.module;
27
28 import java.io.File;
29 import java.io.PrintStream;
30 import java.lang.module.Configuration;
31 import java.lang.module.ModuleDescriptor;
32 import java.lang.module.ModuleFinder;
33 import java.lang.module.ModuleReference;
34 import java.lang.module.ResolvedModule;
35 import java.net.URI;
36 import java.nio.file.Path;
37 import java.util.ArrayList;
38 import java.util.Collections;
39 import java.util.HashMap;
40 import java.util.HashSet;
41 import java.util.Iterator;
42 import java.util.LinkedHashMap;
43 import java.util.List;
44 import java.util.Map;
45 import java.util.Objects;
46 import java.util.Optional;
47 import java.util.Set;
48 import java.util.function.Function;
49 import java.util.stream.Collectors;
50
51 import jdk.internal.access.JavaLangAccess;
52 import jdk.internal.access.JavaLangModuleAccess;
53 import jdk.internal.access.SharedSecrets;
54 import jdk.internal.loader.BootLoader;
55 import jdk.internal.loader.BuiltinClassLoader;
56 import jdk.internal.loader.ClassLoaders;
57 import jdk.internal.misc.VM;
58 import jdk.internal.perf.PerfCounter;
59
60 /**
61 * Initializes/boots the module system.
62 *
63 * The {@link #boot() boot} method is called early in the startup to initialize
64 * the module system. In summary, the boot method creates a Configuration by
65 * resolving a set of module names specified via the launcher (or equivalent)
66 * -m and --add-modules options. The modules are located on a module path that
67 * is constructed from the upgrade module path, system modules, and application
68 * module path. The Configuration is instantiated as the boot layer with each
69 * module in the configuration defined to a class loader.
70 */
71
72 public final class ModuleBootstrap {
73 private ModuleBootstrap() { }
74
75 private static final String JAVA_BASE = "java.base";
76
77 // the token for "all default modules"
78 private static final String ALL_DEFAULT = "ALL-DEFAULT";
79
80 // the token for "all unnamed modules"
81 private static final String ALL_UNNAMED = "ALL-UNNAMED";
82
83 // the token for "all system modules"
84 private static final String ALL_SYSTEM = "ALL-SYSTEM";
85
86 // the token for "all modules on the module path"
87 private static final String ALL_MODULE_PATH = "ALL-MODULE-PATH";
88
89 // access to java.lang/module
90 private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess();
91 private static final JavaLangModuleAccess JLMA = SharedSecrets.getJavaLangModuleAccess();
92
93 // The ModulePatcher for the initial configuration
94 private static final ModulePatcher patcher = initModulePatcher();
95
96 /**
97 * Returns the ModulePatcher for the initial configuration.
98 */
99 public static ModulePatcher patcher() {
100 return patcher;
101 }
102
103 // ModuleFinders for the initial configuration
104 private static volatile ModuleFinder unlimitedFinder;
105 private static volatile ModuleFinder limitedFinder;
106
107 /**
108 * Returns the ModuleFinder for the initial configuration before
109 * observability is limited by the --limit-modules command line option.
110 *
111 * @apiNote Used to support locating modules {@code java.instrument} and
117 return ModuleFinder.ofSystem();
118 } else {
119 return finder;
120 }
121 }
122
123 /**
124 * Returns the ModuleFinder for the initial configuration.
125 *
126 * @apiNote Used to support "{@code java --list-modules}".
127 */
128 public static ModuleFinder limitedFinder() {
129 ModuleFinder finder = limitedFinder;
130 if (finder == null) {
131 return unlimitedFinder();
132 } else {
133 return finder;
134 }
135 }
136
137 /**
138 * Returns true if the archived boot layer can be used. The system properties
139 * are checked in the order that they are used by boot2.
140 */
141 private static boolean canUseArchivedBootLayer() {
142 return getProperty("jdk.module.upgrade.path") == null &&
143 getProperty("jdk.module.path") == null &&
144 getProperty("jdk.module.patch.0") == null && // --patch-module
145 getProperty("jdk.module.main") == null &&
146 getProperty("jdk.module.addmods.0") == null && // --add-modules
147 getProperty("jdk.module.limitmods") == null &&
148 getProperty("jdk.module.addreads.0") == null && // --add-reads
149 getProperty("jdk.module.addexports.0") == null && // --add-exports
150 getProperty("jdk.module.addopens.0") == null && // --add-opens
151 getProperty("jdk.module.illegalAccess") == null;
152 }
153
154 /**
155 * Initialize the module system, returning the boot layer. The boot layer
156 * is obtained from the CDS archive if possible, otherwise it is generated
157 * from the module graph.
158 *
159 * @see java.lang.System#initPhase2(boolean, boolean)
160 */
161 public static ModuleLayer boot() {
162 Counters.start();
163
164 ModuleLayer bootLayer;
165 ArchivedBootLayer archivedBootLayer = ArchivedBootLayer.get();
166 if (archivedBootLayer != null) {
167 assert canUseArchivedBootLayer();
168 bootLayer = archivedBootLayer.bootLayer();
169 BootLoader.getUnnamedModule(); // trigger <clinit> of BootLoader.
170 VM.defineArchivedModules(ClassLoaders.platformClassLoader(), ClassLoaders.appClassLoader());
171
172 // assume boot layer has at least one module providing a service
173 // that is mapped to the application class loader.
174 JLA.bindToLoader(bootLayer, ClassLoaders.appClassLoader());
175
176 // IllegalAccessLogger needs to be set
177 var illegalAccessLoggerBuilder = archivedBootLayer.illegalAccessLoggerBuilder();
178 if (illegalAccessLoggerBuilder != null) {
179 illegalAccessLoggerBuilder.complete();
180 }
181 } else {
182 bootLayer = boot2();
183 }
184
185 Counters.publish("jdk.module.boot.totalTime");
186 return bootLayer;
187 }
188
189 private static ModuleLayer boot2() {
190 // Step 0: Command line options
191
192 ModuleFinder upgradeModulePath = finderFor("jdk.module.upgrade.path");
193 ModuleFinder appModulePath = finderFor("jdk.module.path");
194 boolean isPatched = patcher.hasPatches();
195
196 String mainModule = System.getProperty("jdk.module.main");
197 Set<String> addModules = addModules();
198 Set<String> limitModules = limitModules();
199
200 PrintStream traceOutput = null;
201 String trace = getAndRemoveProperty("jdk.module.showModuleResolution");
202 if (trace != null && Boolean.parseBoolean(trace))
203 traceOutput = System.out;
204
205 Counters.add("jdk.module.boot.0.commandLineTime");
206
207 // Step 1: The observable system modules, either all system modules
208 // or the system modules pre-generated for the initial module (the
209 // initial module may be the unnamed module). If the system modules
433 if (upgradeModulePath != null
434 && upgradeModulePath.find(name).isPresent())
435 fail(name + ": cannot be loaded from upgrade module path");
436 if (!systemModuleFinder.find(name).isPresent())
437 fail(name + ": cannot be loaded from application module path");
438 }
439 }
440 }
441
442 // check for split packages in the modules mapped to the built-in loaders
443 if (hasSplitPackages || isPatched || haveModulePath) {
444 checkSplitPackages(cf, clf);
445 }
446
447 // load/register the modules with the built-in class loaders
448 loadModules(cf, clf);
449 Counters.add("jdk.module.boot.5.loadModulesTime");
450
451 // Step 6: Define all modules to the VM
452
453 ModuleLayer bootLayer = ModuleLayer.empty().defineModules(cf, clf);
454 Counters.add("jdk.module.boot.6.layerCreateTime");
455
456 // Step 7: Miscellaneous
457
458 // check incubating status
459 if (hasIncubatorModules || haveModulePath) {
460 checkIncubatingStatus(cf);
461 }
462
463 // --add-reads, --add-exports/--add-opens, and --illegal-access
464 addExtraReads(bootLayer);
465 boolean extraExportsOrOpens = addExtraExportsAndOpens(bootLayer);
466
467 Map<String, Set<String>> concealedPackagesToOpen;
468 Map<String, Set<String>> exportedPackagesToOpen;
469 if (archivedModuleGraph != null) {
470 concealedPackagesToOpen = archivedModuleGraph.concealedPackagesToOpen();
471 exportedPackagesToOpen = archivedModuleGraph.exportedPackagesToOpen();
472 } else {
473 concealedPackagesToOpen = systemModules.concealedPackagesToOpen();
474 exportedPackagesToOpen = systemModules.exportedPackagesToOpen();
475 }
476 IllegalAccessLogger.Builder builder =
477 addIllegalAccess(upgradeModulePath,
478 concealedPackagesToOpen,
479 exportedPackagesToOpen,
480 bootLayer,
481 extraExportsOrOpens);
482 Counters.add("jdk.module.boot.7.adjustModulesTime");
483
484 // save module finders for later use
485 if (savedModuleFinder != null) {
486 unlimitedFinder = new SafeModuleFinder(savedModuleFinder);
487 if (savedModuleFinder != finder)
488 limitedFinder = new SafeModuleFinder(finder);
489 }
490
491 // Archive module graph and boot layer can be archived at CDS dump time.
492 // Only allow the unnamed module case for now.
493 if (canArchive && (mainModule == null)) {
494 ArchivedModuleGraph.archive(hasSplitPackages,
495 hasIncubatorModules,
496 systemModuleFinder,
497 cf,
498 clf,
499 concealedPackagesToOpen,
500 exportedPackagesToOpen);
501
502 if (!hasSplitPackages && !hasIncubatorModules) {
503 ArchivedBootLayer.archive(bootLayer, builder);
504 }
505 }
506
507 return bootLayer;
508 }
509
510 /**
511 * Load/register the modules to the built-in class loaders.
512 */
513 private static void loadModules(Configuration cf,
514 Function<String, ClassLoader> clf) {
515 for (ResolvedModule resolvedModule : cf.modules()) {
516 ModuleReference mref = resolvedModule.reference();
517 String name = resolvedModule.name();
518 ClassLoader loader = clf.apply(name);
519 if (loader == null) {
520 // skip java.base as it is already loaded
521 if (!name.equals(JAVA_BASE)) {
522 BootLoader.loadModule(mref);
523 }
524 } else if (loader instanceof BuiltinClassLoader) {
525 ((BuiltinClassLoader) loader).loadModule(mref);
866 exportedPackages.add(pn);
867 }
868 }
869 iterator = exportedPackages.iterator();
870 while (iterator.hasNext()) {
871 String pn = iterator.next();
872 if (m.isOpen(pn, BootLoader.getUnnamedModule())) {
873 // exported package is opened to ALL-UNNAMED
874 iterator.remove();
875 }
876 }
877 }
878
879 // log reflective access to all types in concealed packages
880 builder.logAccessToConcealedPackages(m, concealedPackages);
881
882 // log reflective access to non-public members/types in exported packages
883 builder.logAccessToExportedPackages(m, exportedPackages);
884
885 // open the packages to unnamed modules
886 JLA.addOpensToAllUnnamed(m, concealedPackages, exportedPackages);
887 }
888
889 builder.complete();
890 return builder;
891 }
892
893 /**
894 * Decodes the values of --add-reads, -add-exports, --add-opens or
895 * --patch-modules options that are encoded in system properties.
896 *
897 * @param prefix the system property prefix
898 * @praam regex the regex for splitting the RHS of the option value
899 */
900 private static Map<String, List<String>> decode(String prefix,
901 String regex,
902 boolean allowDuplicates) {
903 int index = 0;
904 // the system property is removed after decoding
905 String value = getAndRemoveProperty(prefix + index);
906 if (value == null)
935 }
936 }
937 if (ntargets == 0)
938 fail("Target must be specified: " + option(prefix) + " " + value);
939
940 index++;
941 value = getAndRemoveProperty(prefix + index);
942 }
943
944 return map;
945 }
946
947 /**
948 * Decodes the values of --add-reads, -add-exports or --add-opens
949 * which use the "," to separate the RHS of the option value.
950 */
951 private static Map<String, List<String>> decode(String prefix) {
952 return decode(prefix, ",", true);
953 }
954
955
956 /**
957 * Gets the named system property
958 */
959 private static String getProperty(String key) {
960 return System.getProperty(key);
961 }
962
963 /**
964 * Gets and remove the named system property
965 */
966 private static String getAndRemoveProperty(String key) {
967 return (String) System.getProperties().remove(key);
968 }
969
970 /**
971 * Checks incubating status of modules in the configuration
972 */
973 private static void checkIncubatingStatus(Configuration cf) {
974 String incubating = null;
975 for (ResolvedModule resolvedModule : cf.modules()) {
976 ModuleReference mref = resolvedModule.reference();
977
978 // emit warning if the WARN_INCUBATING module resolution bit set
979 if (ModuleResolution.hasIncubatingWarning(mref)) {
980 String mn = mref.descriptor().name();
981 if (incubating == null) {
982 incubating = mn;
983 } else {
984 incubating += ", " + mn;
985 }
986 }
987 }
|