jdk/src/java.base/share/classes/java/lang/System.java
changeset 36511 9d0388c6b336
parent 36225 6ae0eebc46e9
child 36972 27147cde3256
--- a/jdk/src/java.base/share/classes/java/lang/System.java	Tue Mar 15 13:48:26 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/System.java	Thu Mar 17 19:04:16 2016 +0000
@@ -24,9 +24,23 @@
  */
 package java.lang;
 
-import java.io.*;
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.Console;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.io.UnsupportedEncodingException;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Constructor;
 import java.lang.reflect.Executable;
-import java.lang.annotation.Annotation;
+import java.lang.reflect.Layer;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Module;
+import java.net.URL;
 import java.security.AccessControlContext;
 import java.util.Properties;
 import java.util.PropertyPermission;
@@ -35,6 +49,8 @@
 import java.security.PrivilegedAction;
 import java.nio.channels.Channel;
 import java.nio.channels.spi.SelectorProvider;
+import java.util.stream.Stream;
+
 import java.util.Objects;
 import java.util.ResourceBundle;
 import java.util.function.Supplier;
@@ -51,6 +67,10 @@
 import jdk.internal.logger.LazyLoggers;
 import jdk.internal.logger.LocalizedLoggerWrapper;
 
+import jdk.internal.module.ModuleBootstrap;
+import jdk.internal.module.Modules;
+import jdk.internal.module.ServicesCatalog;
+
 /**
  * The <code>System</code> class contains several useful class fields
  * and methods. It cannot be instantiated.
@@ -65,7 +85,6 @@
  * @since   1.0
  */
 public final class System {
-
     /* register the natives via the static initializer.
      *
      * VM will invoke the initializeSystemClass method to complete
@@ -619,6 +638,24 @@
      * <code>getProperties</code> operation, it may choose to permit the
      * {@link #getProperty(String)} operation.
      *
+     * @implNote In addition to the standard system properties, the {@code
+     * java} launcher may create the Java Virtual Machine with system
+     * properties that have the following keys:
+     * <table summary="Shows property keys and associated values">
+     * <tr><th>Key</th>
+     *     <th>Description of Associated Value</th></tr>
+     * <tr><td>{@code jdk.module.path}</td>
+     *     <td>Application module path</td></tr>
+     * <tr><td>{@code jdk.upgrade.module.path}</td>
+     *     <td>The upgrade module path</td></tr>
+     * <tr><td>{@code jdk.module.main}</td>
+     *     <td>The module name of the initial/main module</td></tr>
+     * <tr><td>{@code jdk.module.main.class}</td>
+     *     <td>The main class name of the initial module</td></tr>
+     * </table>
+     * These properties may also be set by custom launchers that use the JNI
+     * invocation API to create the Java Virtual Machine.
+     *
      * @return     the system properties
      * @exception  SecurityException  if a security manager exists and its
      *             <code>checkPropertiesAccess</code> method doesn't allow access
@@ -1795,11 +1832,10 @@
         return new PrintStream(new BufferedOutputStream(fos, 128), true);
     }
 
-
     /**
      * Initialize the system class.  Called after thread initialization.
      */
-    private static void initializeSystemClass() {
+    private static void initPhase1() {
 
         // VM might invoke JNU_NewStringPlatform() to set those encoding
         // sensitive properties (user.home, user.name, boot.class.path, etc.)
@@ -1828,7 +1864,6 @@
         // certain system properties that are not intended for public access.
         VM.saveAndRemoveProperties(props);
 
-
         lineSeparator = props.getProperty("line.separator");
         VersionProps.init();
 
@@ -1862,9 +1897,81 @@
 
         // Subsystems that are invoked during initialization can invoke
         // VM.isBooted() in order to avoid doing things that should
-        // wait until the application class loader has been set up.
+        // wait until the VM is fully initialized. The initialization level
+        // is incremented from 0 to 1 here to indicate the first phase of
+        // initialization has completed.
         // IMPORTANT: Ensure that this remains the last initialization action!
-        VM.booted();
+        VM.initLevel(1);
+    }
+
+    // @see #initPhase2()
+    private static Layer bootLayer;
+
+    /*
+     * Invoked by VM.  Phase 2 module system initialization.
+     * Only classes in java.base can be loaded in this phase.
+     */
+    private static void initPhase2() {
+        // initialize the module system
+        System.bootLayer = ModuleBootstrap.boot();
+
+        // base module needs to be loose (CODETOOLS-7901619)
+        Module base = Object.class.getModule();
+        Modules.addReads(base, null);
+
+        // module system initialized
+        VM.initLevel(2);
+    }
+
+    /*
+     * Invoked by VM.  Phase 3 is the final system initialization:
+     * 1. set security manager
+     * 2. set system class loader
+     * 3. set TCCL
+     *
+     * This method must be called after the module system initialization.
+     * The security manager and system class loader may be custom class from
+     * the application classpath or modulepath.
+     */
+    private static void initPhase3() {
+        // set security manager
+        String cn = System.getProperty("java.security.manager");
+        if (cn != null) {
+            if (cn.isEmpty() || "default".equals(cn)) {
+                System.setSecurityManager(new SecurityManager());
+            } else {
+                try {
+                    Class<?> c = Class.forName(cn, false, ClassLoader.getBuiltinAppClassLoader());
+                    Constructor<?> ctor = c.getConstructor();
+                    // Must be a public subclass of SecurityManager with
+                    // a public no-arg constructor
+                    if (!SecurityManager.class.isAssignableFrom(c) ||
+                            !Modifier.isPublic(c.getModifiers()) ||
+                            !Modifier.isPublic(ctor.getModifiers())) {
+                        throw new Error("Could not create SecurityManager: " + ctor.toString());
+                    }
+                    // custom security manager implementation may be in unnamed module
+                    // or a named module but non-exported package
+                    ctor.setAccessible(true);
+                    SecurityManager sm = (SecurityManager) ctor.newInstance();
+                    System.setSecurityManager(sm);
+                } catch (Exception e) {
+                    throw new Error("Could not create SecurityManager", e);
+                }
+            }
+        }
+
+        // initializing the system class loader
+        VM.initLevel(3);
+
+        // system class loader initialized
+        ClassLoader scl = ClassLoader.initSystemClassLoader();
+
+        // set TCCL
+        Thread.currentThread().setContextClassLoader(scl);
+
+        // system is fully initialized
+        VM.initLevel(4);
     }
 
     private static void setJavaLangAccess() {
@@ -1910,6 +2017,27 @@
             public void invokeFinalize(Object o) throws Throwable {
                 o.finalize();
             }
+            public Layer getBootLayer() {
+                return bootLayer;
+            }
+            public ServicesCatalog getServicesCatalog(ClassLoader cl) {
+                return cl.getServicesCatalog();
+            }
+            public ServicesCatalog createOrGetServicesCatalog(ClassLoader cl) {
+                return cl.createOrGetServicesCatalog();
+            }
+            public Class<?> findBootstrapClassOrNull(ClassLoader cl, String name) {
+                return cl.findBootstrapClassOrNull(name);
+            }
+            public URL findResource(ClassLoader cl, String mn, String name) throws IOException {
+                return cl.findResource(mn, name);
+            }
+            public Stream<Package> packages(ClassLoader cl) {
+                return cl.packages();
+            }
+            public Package definePackage(ClassLoader cl, String name, Module module) {
+                return cl.definePackage(name, module);
+            }
             public String fastUUID(long lsb, long msb) {
                 return Long.fastUUID(lsb, msb);
             }