jdk/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java
changeset 45004 ea3137042a61
parent 44545 83b611b88ac8
child 45652 33342314ce89
--- a/jdk/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java	Mon Apr 24 13:43:34 2017 +0800
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java	Thu May 04 07:26:55 2017 +0000
@@ -84,8 +84,9 @@
     // The ModulePatcher for the initial configuration
     private static final ModulePatcher patcher = initModulePatcher();
 
-    // ModuleFinder for the initial configuration
-    private static ModuleFinder initialFinder;
+    // ModuleFinders for the initial configuration
+    private static ModuleFinder unlimitedFinder;
+    private static ModuleFinder limitedFinder;
 
     /**
      * Returns the ModulePatcher for the initial configuration.
@@ -95,11 +96,20 @@
     }
 
     /**
-     * Returns the ModuleFinder for the initial configuration
+     * Returns the ModuleFinder for the initial configuration before observability
+     * is limited by the --limit-modules command line option.
      */
-    public static ModuleFinder finder() {
-        assert initialFinder != null;
-        return initialFinder;
+    public static ModuleFinder unlimitedFinder() {
+        assert unlimitedFinder != null;
+        return unlimitedFinder;
+    }
+
+    /**
+     * Returns the ModuleFinder for the initial configuration.
+     */
+    public static ModuleFinder limitedFinder() {
+        assert limitedFinder != null;
+        return limitedFinder;
     }
 
     /**
@@ -134,6 +144,11 @@
 
         PerfCounters.defineBaseTime.addElapsedTimeFrom(t1);
 
+        // special mode to boot with only java.base, ignores other options
+        String propValue = getAndRemoveProperty("jdk.module.minimumBoot");
+        if (propValue != null) {
+            return createMinimalBootLayer();
+        }
 
         long t2 = System.nanoTime();
 
@@ -180,7 +195,8 @@
         }
 
         // --limit-modules
-        String propValue = getAndRemoveProperty("jdk.module.limitmods");
+        unlimitedFinder = finder;
+        propValue = getAndRemoveProperty("jdk.module.limitmods");
         if (propValue != null) {
             Set<String> mods = new HashSet<>();
             for (String mod: propValue.split(",")) {
@@ -188,6 +204,7 @@
             }
             finder = limitFinder(finder, mods, roots);
         }
+        limitedFinder = finder;
 
         // If there is no initial module specified then assume that the initial
         // module is the unnamed module of the application class loader. This
@@ -267,7 +284,8 @@
         }
 
         PrintStream traceOutput = null;
-        if (Boolean.getBoolean("jdk.launcher.traceResolver"))
+        propValue = getAndRemoveProperty("jdk.module.showModuleResolution");
+        if (propValue != null && Boolean.parseBoolean(propValue))
             traceOutput = System.out;
 
         // run the resolver to create the configuration
@@ -362,10 +380,21 @@
         // total time to initialize
         PerfCounters.bootstrapTime.addElapsedTimeFrom(t0);
 
-        // remember the ModuleFinder
-        initialFinder = finder;
+        return bootLayer;
+    }
 
-        return bootLayer;
+    /**
+     * Create a "minimal" boot module layer that only contains java.base.
+     */
+    private static ModuleLayer createMinimalBootLayer() {
+        Configuration cf = SharedSecrets.getJavaLangModuleAccess()
+            .resolveAndBind(ModuleFinder.ofSystem(),
+                            Set.of(JAVA_BASE),
+                            false,
+                            null);
+
+        Function<String, ClassLoader> clf = ModuleLoaderMap.mappingFunction(cf);
+        return ModuleLayer.empty().defineModules(cf, clf);
     }
 
     /**