< prev index next >

src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java

Print this page

@@ -40,24 +40,23 @@
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.NoSuchElementException;
 import java.util.Objects;
 import java.util.Optional;
 import java.util.Set;
 import java.util.function.Function;
 import java.util.stream.Collectors;
 
+import jdk.internal.access.JavaLangAccess;
+import jdk.internal.access.JavaLangModuleAccess;
+import jdk.internal.access.SharedSecrets;
 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;
 
 /**
  * Initializes/boots the module system.
  *

@@ -86,12 +85,12 @@
 
     // the token for "all modules on the module path"
     private static final String ALL_MODULE_PATH = "ALL-MODULE-PATH";
 
     // access to java.lang/module
-    private static final JavaLangModuleAccess JLMA
-        = SharedSecrets.getJavaLangModuleAccess();
+    private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess();
+    private static final JavaLangModuleAccess JLMA = SharedSecrets.getJavaLangModuleAccess();
 
     // The ModulePatcher for the initial configuration
     private static final ModulePatcher patcher = initModulePatcher();
 
     /**

@@ -133,120 +132,63 @@
         } 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;
+    /**
+     * Returns true if the archived boot layer can be used. The system properties
+     * are checked in the order that they are used by boot2.
+     */
+    private static boolean canUseArchivedBootLayer() {
+        return getProperty("jdk.module.upgrade.path") == null &&
+               getProperty("jdk.module.path") == null &&
+               getProperty("jdk.module.patch.0") == null &&    // --patch-module
+               getProperty("jdk.module.main") == null &&
+               getProperty("jdk.module.addmods.0") == null  && // --add-modules
+               getProperty("jdk.module.limitmods") == null &&
+               getProperty("jdk.module.addreads.0") == null &&    // --add-reads
+               getProperty("jdk.module.addexports.0") == null &&  // --add-exports
+               getProperty("jdk.module.addopens.0") == null &&    // --add-opens
+               getProperty("jdk.module.illegalAccess") == 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;
-        }
-    }
+    /**
+     * Initialize the module system, returning the boot layer. The boot layer
+     * is obtained from the CDS archive if possible, otherwise it is generated
+     * from the module graph.
+     *
+     * @see java.lang.System#initPhase2(boolean, boolean)
+     */
+    public static ModuleLayer boot() {
+        Counters.start();
 
-    private static ModuleLayer getArchivedBootLayer() {
+        ModuleLayer bootLayer;
         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;
+            assert canUseArchivedBootLayer();
+            bootLayer = archivedBootLayer.bootLayer();
+            BootLoader.getUnnamedModule(); // trigger <clinit> of BootLoader.
+            VM.defineArchivedModules(ClassLoaders.platformClassLoader(), ClassLoaders.appClassLoader());
+
+            // assume boot layer has at least one module providing a service
+            // that is mapped to the application class loader.
+            JLA.bindToLoader(bootLayer, ClassLoaders.appClassLoader());
+
+            // IllegalAccessLogger needs to be set
+            var illegalAccessLoggerBuilder = archivedBootLayer.illegalAccessLoggerBuilder();
+            if (illegalAccessLoggerBuilder != null) {
+                illegalAccessLoggerBuilder.complete();
         }
-
-        return null;
+        } else {
+            bootLayer = boot2();
     }
 
-
-    /**
-     * 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) {
+        Counters.publish("jdk.module.boot.totalTime");
             return bootLayer;
         }
 
+    private static ModuleLayer boot2() {
         // Step 0: Command line options
 
         ModuleFinder upgradeModulePath = finderFor("jdk.module.upgrade.path");
         ModuleFinder appModulePath = finderFor("jdk.module.path");
         boolean isPatched = patcher.hasPatches();

@@ -506,11 +448,11 @@
         loadModules(cf, clf);
         Counters.add("jdk.module.boot.5.loadModulesTime");
 
         // Step 6: Define all modules to the VM
 
-        bootLayer = ModuleLayer.empty().defineModules(cf, clf);
+        ModuleLayer bootLayer = ModuleLayer.empty().defineModules(cf, clf);
         Counters.add("jdk.module.boot.6.layerCreateTime");
 
         // Step 7: Miscellaneous
 
         // check incubating status

@@ -544,30 +486,25 @@
             unlimitedFinder = new SafeModuleFinder(savedModuleFinder);
             if (savedModuleFinder != finder)
                 limitedFinder = new SafeModuleFinder(finder);
         }
 
-        // Module graph can be archived at CDS dump time. Only allow the
-        // unnamed module case for now.
+        // Archive module graph and boot layer can be archived at CDS dump time.
+        // Only allow the unnamed module case for now.
         if (canArchive && (mainModule == null)) {
-            ArchivedModuleGraph.archive(
-                    new ArchivedModuleGraph(hasSplitPackages,
+            ArchivedModuleGraph.archive(hasSplitPackages,
                                             hasIncubatorModules,
                                             systemModuleFinder,
                                             cf,
                                             clf,
                                             concealedPackagesToOpen,
-                                            exportedPackagesToOpen));
-            ArchivedBootLayer.archive(
-                    new ArchivedBootLayer(bootLayer,
-                                          limitedFinder,
-                                          unlimitedFinder,
-                                          builder));
-        }
+                                        exportedPackagesToOpen);
 
-        // total time to initialize
-        Counters.publish("jdk.module.boot.totalTime");
+            if (!hasSplitPackages && !hasIncubatorModules) {
+                ArchivedBootLayer.archive(bootLayer, builder);
+            }
+        }
 
         return bootLayer;
     }
 
     /**

@@ -944,12 +881,11 @@
 
             // log reflective access to non-public members/types in exported packages
             builder.logAccessToExportedPackages(m, exportedPackages);
 
             // open the packages to unnamed modules
-            JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
-            jla.addOpensToAllUnnamed(m, concealedPackages, exportedPackages);
+            JLA.addOpensToAllUnnamed(m, concealedPackages, exportedPackages);
         }
 
         builder.complete();
         return builder;
     }

@@ -1014,15 +950,23 @@
      */
     private static Map<String, List<String>> decode(String prefix) {
         return decode(prefix, ",", true);
     }
 
+
+    /**
+     * Gets the named system property
+     */
+    private static String getProperty(String key) {
+        return System.getProperty(key);
+    }
+
     /**
      * Gets and remove the named system property
      */
     private static String getAndRemoveProperty(String key) {
-        return (String)System.getProperties().remove(key);
+        return (String) System.getProperties().remove(key);
     }
 
     /**
      * Checks incubating status of modules in the configuration
      */
< prev index next >