< prev index next >
src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java
Print this page
@@ -49,10 +49,12 @@
import java.util.function.Function;
import java.util.stream.Collectors;
import jdk.internal.loader.BootLoader;
import jdk.internal.loader.BuiltinClassLoader;
+import jdk.internal.loader.ClassLoaders;
+import jdk.internal.misc.VM;
import jdk.internal.access.JavaLangAccess;
import jdk.internal.access.JavaLangModuleAccess;
import jdk.internal.access.SharedSecrets;
import jdk.internal.perf.PerfCounter;
@@ -131,18 +133,119 @@
} else {
return finder;
}
}
+ private static class ArchivedBootLayer {
+ private static ArchivedBootLayer archivedBootLayer;
+
+ private final ModuleLayer bootLayer;
+ private final ModuleFinder limitedFinder;
+ private final IllegalAccessLogger.Builder builder;
+ private final ModuleFinder unlimitedFinder;
+ private final ServicesCatalog platformCatalog;
+ private final ServicesCatalog appCatalog;
+
+ public ArchivedBootLayer(ModuleLayer bootLayer,
+ ModuleFinder limitedFinder,
+ ModuleFinder unlimitedFinder,
+ IllegalAccessLogger.Builder builder) {
+ this.bootLayer = bootLayer;
+ this.limitedFinder = limitedFinder;
+ this.unlimitedFinder = unlimitedFinder;
+ this.builder = builder;
+
+ this.platformCatalog = ServicesCatalog.getServicesCatalog(ClassLoaders.platformClassLoader());
+ this.appCatalog = ServicesCatalog.getServicesCatalog(ClassLoaders.appClassLoader());
+ }
+
+ static ArchivedBootLayer get() {
+ // The VM will initialize archivedBootLayer only if MetaspaceShared::use_full_module_graph() is true.
+ return archivedBootLayer;
+ }
+
+ static void archive(ArchivedBootLayer layer) {
+ archivedBootLayer = layer;
+ }
+
+ static {
+ VM.initializeFromArchive(ArchivedBootLayer.class);
+ }
+ }
+
+ private static boolean hasProperty(String key) {
+ return System.getProperty(key) != null;
+ }
+
+ private static boolean mayUseArchivedBootLayer() {
+ // If these properties are set, we cannot use the archived boot layer.
+ // The VM should have already checked this before initializing
+ // ArchivedBootLayer::archivedBootLayer.
+ if (hasProperty("jdk.module.upgrade.path") ||
+ hasProperty("jdk.module.main") ||
+ hasProperty("jdk.module.limitmods") ||
+ hasProperty("jdk.module.validation") ||
+ hasProperty("jdk.module.showModuleResolution") ||
+ hasProperty("jdk.module.illegalAccess") ||
+ hasProperty("java.system.class.loader") ||
+ hasProperty("jdk.module.addexports.0") ||
+ hasProperty("jdk.module.addopens.0") ||
+ hasProperty("jdk.module.addreads.0") ||
+ hasProperty("jdk.module.patch.0") ||
+ hasProperty("jdk.module.addmods.0")) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ private static ModuleLayer getArchivedBootLayer() {
+ ArchivedBootLayer archivedBootLayer = ArchivedBootLayer.get();
+ if (archivedBootLayer != null) {
+ assert mayUseArchivedBootLayer();
+ Counters.add("jdk.module.boot.0.archivedBootLayer");
+ limitedFinder = archivedBootLayer.limitedFinder;
+ unlimitedFinder = archivedBootLayer.unlimitedFinder;
+ ModuleLayer bootLayer = archivedBootLayer.bootLayer;
+
+ // Trigger BootLoader.<clinit>
+ BootLoader.getUnnamedModule();
+
+ // BootLoader.SERVICES_CATALOG is saved/restored separately in BootLoader.java
+ ServicesCatalog.setServicesCatalog(ClassLoaders.platformClassLoader(),
+ archivedBootLayer.platformCatalog);
+ ServicesCatalog.setServicesCatalog(ClassLoaders.appClassLoader(),
+ archivedBootLayer.appCatalog);
+
+ JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
+ jla.bindToLoader(bootLayer, ClassLoaders.appClassLoader());
+
+ IllegalAccessLogger.Builder builder = archivedBootLayer.builder;
+ if (builder != null) {
+ builder.complete();
+ }
+
+ Counters.publish("jdk.module.boot.totalTime");
+ return bootLayer;
+ }
+
+ return null;
+ }
+
+
/**
* Initialize the module system, returning the boot layer.
*
* @see java.lang.System#initPhase2(boolean, boolean)
*/
public static ModuleLayer boot() throws Exception {
Counters.start();
+ ModuleLayer bootLayer = getArchivedBootLayer();
+ if (bootLayer != null) {
+ return bootLayer;
+ }
// Step 0: Command line options
ModuleFinder upgradeModulePath = finderFor("jdk.module.upgrade.path");
ModuleFinder appModulePath = finderFor("jdk.module.path");
@@ -403,11 +506,11 @@
loadModules(cf, clf);
Counters.add("jdk.module.boot.5.loadModulesTime");
// Step 6: Define all modules to the VM
- ModuleLayer bootLayer = ModuleLayer.empty().defineModules(cf, clf);
+ bootLayer = ModuleLayer.empty().defineModules(cf, clf);
Counters.add("jdk.module.boot.6.layerCreateTime");
// Step 7: Miscellaneous
// check incubating status
@@ -426,10 +529,11 @@
exportedPackagesToOpen = archivedModuleGraph.exportedPackagesToOpen();
} else {
concealedPackagesToOpen = systemModules.concealedPackagesToOpen();
exportedPackagesToOpen = systemModules.exportedPackagesToOpen();
}
+ IllegalAccessLogger.Builder builder =
addIllegalAccess(upgradeModulePath,
concealedPackagesToOpen,
exportedPackagesToOpen,
bootLayer,
extraExportsOrOpens);
@@ -451,10 +555,15 @@
systemModuleFinder,
cf,
clf,
concealedPackagesToOpen,
exportedPackagesToOpen));
+ ArchivedBootLayer.archive(
+ new ArchivedBootLayer(bootLayer,
+ limitedFinder,
+ unlimitedFinder,
+ builder));
}
// total time to initialize
Counters.publish("jdk.module.boot.totalTime");
@@ -749,21 +858,22 @@
/**
* Process the --illegal-access option (and its default) to open packages
* of system modules in the boot layer to code in unnamed modules.
*/
- private static void addIllegalAccess(ModuleFinder upgradeModulePath,
+ private static IllegalAccessLogger.Builder
+ addIllegalAccess(ModuleFinder upgradeModulePath,
Map<String, Set<String>> concealedPackagesToOpen,
Map<String, Set<String>> exportedPackagesToOpen,
ModuleLayer bootLayer,
boolean extraExportsOrOpens) {
String value = getAndRemoveProperty("jdk.module.illegalAccess");
IllegalAccessLogger.Mode mode = IllegalAccessLogger.Mode.ONESHOT;
if (value != null) {
switch (value) {
case "deny":
- return;
+ return null;
case "permit":
break;
case "warn":
mode = IllegalAccessLogger.Mode.WARN;
break;
@@ -771,11 +881,11 @@
mode = IllegalAccessLogger.Mode.DEBUG;
break;
default:
fail("Value specified to --illegal-access not recognized:"
+ " '" + value + "'");
- return;
+ return null;
}
}
IllegalAccessLogger.Builder builder
= new IllegalAccessLogger.Builder(mode, System.err);
@@ -839,10 +949,11 @@
JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
jla.addOpensToAllUnnamed(m, concealedPackages, exportedPackages);
}
builder.complete();
+ return builder;
}
/**
* Decodes the values of --add-reads, -add-exports, --add-opens or
* --patch-modules options that are encoded in system properties.
< prev index next >