< prev index next >

src/java.base/share/classes/java/lang/System.java

Print this page
rev 52582 : 4947890: Minimize JNI upcalls in system-properties initialization
Reviewed-by: erikj


  55 import java.util.Objects;
  56 import java.util.Properties;
  57 import java.util.PropertyPermission;
  58 import java.util.ResourceBundle;
  59 import java.util.function.Supplier;
  60 import java.util.concurrent.ConcurrentHashMap;
  61 import java.util.stream.Stream;
  62 
  63 import jdk.internal.util.StaticProperty;
  64 import jdk.internal.module.ModuleBootstrap;
  65 import jdk.internal.module.ServicesCatalog;
  66 import jdk.internal.reflect.CallerSensitive;
  67 import jdk.internal.reflect.Reflection;
  68 import jdk.internal.HotSpotIntrinsicCandidate;
  69 import jdk.internal.access.JavaLangAccess;
  70 import jdk.internal.access.SharedSecrets;
  71 import jdk.internal.misc.VM;
  72 import jdk.internal.logger.LoggerFinderLoader;
  73 import jdk.internal.logger.LazyLoggers;
  74 import jdk.internal.logger.LocalizedLoggerWrapper;

  75 import jdk.internal.vm.annotation.Stable;
  76 import sun.reflect.annotation.AnnotationType;
  77 import sun.nio.ch.Interruptible;
  78 import sun.security.util.SecurityConstants;
  79 
  80 /**
  81  * The {@code System} class contains several useful class fields
  82  * and methods. It cannot be instantiated.
  83  *
  84  * Among the facilities provided by the {@code System} class
  85  * are standard input, standard output, and error output streams;
  86  * access to externally defined properties and environment
  87  * variables; a means of loading files and libraries; and a utility
  88  * method for quickly copying a portion of an array.
  89  *
  90  * @since   1.0
  91  */
  92 public final class System {
  93     /* Register the natives via the static initializer.
  94      *


 588      * <dt>java.version.date    <dd>Java version date
 589      * <dt>java.vendor          <dd>Java vendor specific string
 590      * <dt>java.vendor.url      <dd>Java vendor URL
 591      * <dt>java.vendor.version  <dd>Java vendor version
 592      * <dt>java.home            <dd>Java installation directory
 593      * <dt>java.class.version   <dd>Java class version number
 594      * <dt>java.class.path      <dd>Java classpath
 595      * <dt>os.name              <dd>Operating System Name
 596      * <dt>os.arch              <dd>Operating System Architecture
 597      * <dt>os.version           <dd>Operating System Version
 598      * <dt>file.separator       <dd>File separator ("/" on Unix)
 599      * <dt>path.separator       <dd>Path separator (":" on Unix)
 600      * <dt>line.separator       <dd>Line separator ("\n" on Unix)
 601      * <dt>user.name            <dd>User account name
 602      * <dt>user.home            <dd>User home directory
 603      * <dt>user.dir             <dd>User's current working directory
 604      * </dl>
 605      */
 606 
 607     private static Properties props;
 608     private static native Properties initProperties(Properties props);
 609 
 610     /**
 611      * Determines the current system properties.
 612      *
 613      * First, if there is a security manager, its
 614      * {@code checkPropertiesAccess} method is called with no
 615      * arguments. This may result in a security exception.
 616      * <p>
 617      * The current set of system properties for use by the
 618      * {@link #getProperty(String)} method is returned as a
 619      * {@code Properties} object. If there is no current set of
 620      * system properties, a set of system properties is first created and
 621      * initialized. This set of system properties always includes values
 622      * for the following keys:
 623      * <table class="striped" style="text-align:left">
 624      * <caption style="display:none">Shows property keys and associated values</caption>
 625      * <thead>
 626      * <tr><th scope="col">Key</th>
 627      *     <th scope="col">Description of Associated Value</th></tr>
 628      * </thead>


 782      *
 783      * @apiNote
 784      * <strong>Changing a standard system property may have unpredictable results
 785      * unless otherwise specified</strong>.
 786      * See {@linkplain #getProperties getProperties} for details.
 787      *
 788      * @param      props   the new system properties.
 789      * @throws     SecurityException  if a security manager exists and its
 790      *             {@code checkPropertiesAccess} method doesn't allow access
 791      *             to the system properties.
 792      * @see        #getProperties
 793      * @see        java.util.Properties
 794      * @see        java.lang.SecurityException
 795      * @see        java.lang.SecurityManager#checkPropertiesAccess()
 796      */
 797     public static void setProperties(Properties props) {
 798         SecurityManager sm = getSecurityManager();
 799         if (sm != null) {
 800             sm.checkPropertiesAccess();
 801         }

 802         if (props == null) {
 803             props = new Properties();
 804             initProperties(props);
 805             VersionProps.init(props);
 806         }
 807         System.props = props;
 808     }
 809 
 810     /**
 811      * Gets the system property indicated by the specified key.
 812      *
 813      * First, if there is a security manager, its
 814      * {@code checkPropertyAccess} method is called with the key as
 815      * its argument. This may result in a SecurityException.
 816      * <p>
 817      * If there is no current set of system properties, a set of system
 818      * properties is first created and initialized in the same manner as
 819      * for the {@code getProperties} method.
 820      *
 821      * @apiNote
 822      * <strong>Changing a standard system property may have unpredictable results
 823      * unless otherwise specified</strong>.
 824      * See {@linkplain #getProperties getProperties} for details.


1949             e.printStackTrace(log);
1950         } else {
1951             log.println(e);
1952             for (Throwable suppressed : e.getSuppressed()) {
1953                 log.println("Suppressed: " + suppressed);
1954             }
1955             Throwable cause = e.getCause();
1956             if (cause != null) {
1957                 log.println("Caused by: " + cause);
1958             }
1959         }
1960     }
1961 
1962     /**
1963      * Initialize the system class.  Called after thread initialization.
1964      */
1965     private static void initPhase1() {
1966 
1967         // VM might invoke JNU_NewStringPlatform() to set those encoding
1968         // sensitive properties (user.home, user.name, boot.class.path, etc.)
1969         // during "props" initialization, in which it may need access, via
1970         // System.getProperty(), to the related system encoding property that
1971         // have been initialized (put into "props") at early stage of the
1972         // initialization. So make sure the "props" is available at the
1973         // very beginning of the initialization and all system properties to
1974         // be put into it directly.
1975         props = new Properties(84);
1976         initProperties(props);  // initialized by the VM
1977         VersionProps.init(props);
1978 
1979         // There are certain system configurations that may be controlled by
1980         // VM options such as the maximum amount of direct memory and
1981         // Integer cache size used to support the object identity semantics
1982         // of autoboxing.  Typically, the library will obtain these values
1983         // from the properties set by the VM.  If the properties are for
1984         // internal implementation use only, these properties should be
1985         // removed from the system properties.
1986         //
1987         // See java.lang.Integer.IntegerCache and the
1988         // VM.saveAndRemoveProperties method for example.
1989         //
1990         // Save a private copy of the system properties object that
1991         // can only be accessed by the internal implementation.  Remove
1992         // certain system properties that are not intended for public access.
1993         VM.saveAndRemoveProperties(props);
1994 
1995         lineSeparator = props.getProperty("line.separator");
1996         StaticProperty.javaHome();          // Load StaticProperty to cache the property values
1997 
1998         FileInputStream fdIn = new FileInputStream(FileDescriptor.in);
1999         FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out);
2000         FileOutputStream fdErr = new FileOutputStream(FileDescriptor.err);
2001         setIn0(new BufferedInputStream(fdIn));
2002         setOut0(newPrintStream(fdOut, props.getProperty("sun.stdout.encoding")));
2003         setErr0(newPrintStream(fdErr, props.getProperty("sun.stderr.encoding")));
2004 
2005         // Setup Java signal handlers for HUP, TERM, and INT (where available).
2006         Terminator.setup();
2007 
2008         // Initialize any miscellaneous operating system settings that need to be
2009         // set for the class libraries. Currently this is no-op everywhere except
2010         // for Windows where the process-wide error mode is set before the java.io
2011         // classes are used.
2012         VM.initializeOSEnvironment();
2013 
2014         // The main thread is not added to its thread group in the same
2015         // way as other threads; we must do it ourselves here.
2016         Thread current = Thread.currentThread();




  55 import java.util.Objects;
  56 import java.util.Properties;
  57 import java.util.PropertyPermission;
  58 import java.util.ResourceBundle;
  59 import java.util.function.Supplier;
  60 import java.util.concurrent.ConcurrentHashMap;
  61 import java.util.stream.Stream;
  62 
  63 import jdk.internal.util.StaticProperty;
  64 import jdk.internal.module.ModuleBootstrap;
  65 import jdk.internal.module.ServicesCatalog;
  66 import jdk.internal.reflect.CallerSensitive;
  67 import jdk.internal.reflect.Reflection;
  68 import jdk.internal.HotSpotIntrinsicCandidate;
  69 import jdk.internal.access.JavaLangAccess;
  70 import jdk.internal.access.SharedSecrets;
  71 import jdk.internal.misc.VM;
  72 import jdk.internal.logger.LoggerFinderLoader;
  73 import jdk.internal.logger.LazyLoggers;
  74 import jdk.internal.logger.LocalizedLoggerWrapper;
  75 import jdk.internal.util.SystemProps;
  76 import jdk.internal.vm.annotation.Stable;
  77 import sun.reflect.annotation.AnnotationType;
  78 import sun.nio.ch.Interruptible;
  79 import sun.security.util.SecurityConstants;
  80 
  81 /**
  82  * The {@code System} class contains several useful class fields
  83  * and methods. It cannot be instantiated.
  84  *
  85  * Among the facilities provided by the {@code System} class
  86  * are standard input, standard output, and error output streams;
  87  * access to externally defined properties and environment
  88  * variables; a means of loading files and libraries; and a utility
  89  * method for quickly copying a portion of an array.
  90  *
  91  * @since   1.0
  92  */
  93 public final class System {
  94     /* Register the natives via the static initializer.
  95      *


 589      * <dt>java.version.date    <dd>Java version date
 590      * <dt>java.vendor          <dd>Java vendor specific string
 591      * <dt>java.vendor.url      <dd>Java vendor URL
 592      * <dt>java.vendor.version  <dd>Java vendor version
 593      * <dt>java.home            <dd>Java installation directory
 594      * <dt>java.class.version   <dd>Java class version number
 595      * <dt>java.class.path      <dd>Java classpath
 596      * <dt>os.name              <dd>Operating System Name
 597      * <dt>os.arch              <dd>Operating System Architecture
 598      * <dt>os.version           <dd>Operating System Version
 599      * <dt>file.separator       <dd>File separator ("/" on Unix)
 600      * <dt>path.separator       <dd>Path separator (":" on Unix)
 601      * <dt>line.separator       <dd>Line separator ("\n" on Unix)
 602      * <dt>user.name            <dd>User account name
 603      * <dt>user.home            <dd>User home directory
 604      * <dt>user.dir             <dd>User's current working directory
 605      * </dl>
 606      */
 607 
 608     private static Properties props;

 609 
 610     /**
 611      * Determines the current system properties.
 612      *
 613      * First, if there is a security manager, its
 614      * {@code checkPropertiesAccess} method is called with no
 615      * arguments. This may result in a security exception.
 616      * <p>
 617      * The current set of system properties for use by the
 618      * {@link #getProperty(String)} method is returned as a
 619      * {@code Properties} object. If there is no current set of
 620      * system properties, a set of system properties is first created and
 621      * initialized. This set of system properties always includes values
 622      * for the following keys:
 623      * <table class="striped" style="text-align:left">
 624      * <caption style="display:none">Shows property keys and associated values</caption>
 625      * <thead>
 626      * <tr><th scope="col">Key</th>
 627      *     <th scope="col">Description of Associated Value</th></tr>
 628      * </thead>


 782      *
 783      * @apiNote
 784      * <strong>Changing a standard system property may have unpredictable results
 785      * unless otherwise specified</strong>.
 786      * See {@linkplain #getProperties getProperties} for details.
 787      *
 788      * @param      props   the new system properties.
 789      * @throws     SecurityException  if a security manager exists and its
 790      *             {@code checkPropertiesAccess} method doesn't allow access
 791      *             to the system properties.
 792      * @see        #getProperties
 793      * @see        java.util.Properties
 794      * @see        java.lang.SecurityException
 795      * @see        java.lang.SecurityManager#checkPropertiesAccess()
 796      */
 797     public static void setProperties(Properties props) {
 798         SecurityManager sm = getSecurityManager();
 799         if (sm != null) {
 800             sm.checkPropertiesAccess();
 801         }
 802 
 803         if (props == null) {
 804             props = SystemProps.initProperties();

 805             VersionProps.init(props);
 806         }
 807         System.props = props;
 808     }
 809 
 810     /**
 811      * Gets the system property indicated by the specified key.
 812      *
 813      * First, if there is a security manager, its
 814      * {@code checkPropertyAccess} method is called with the key as
 815      * its argument. This may result in a SecurityException.
 816      * <p>
 817      * If there is no current set of system properties, a set of system
 818      * properties is first created and initialized in the same manner as
 819      * for the {@code getProperties} method.
 820      *
 821      * @apiNote
 822      * <strong>Changing a standard system property may have unpredictable results
 823      * unless otherwise specified</strong>.
 824      * See {@linkplain #getProperties getProperties} for details.


1949             e.printStackTrace(log);
1950         } else {
1951             log.println(e);
1952             for (Throwable suppressed : e.getSuppressed()) {
1953                 log.println("Suppressed: " + suppressed);
1954             }
1955             Throwable cause = e.getCause();
1956             if (cause != null) {
1957                 log.println("Caused by: " + cause);
1958             }
1959         }
1960     }
1961 
1962     /**
1963      * Initialize the system class.  Called after thread initialization.
1964      */
1965     private static void initPhase1() {
1966 
1967         // VM might invoke JNU_NewStringPlatform() to set those encoding
1968         // sensitive properties (user.home, user.name, boot.class.path, etc.)
1969         // during "props" initialization.
1970         // The charset is initialized in System.c and does not depend on the Properties.
1971         props = SystemProps.initProperties();





1972         VersionProps.init(props);
1973 
1974         // There are certain system configurations that may be controlled by
1975         // VM options such as the maximum amount of direct memory and
1976         // Integer cache size used to support the object identity semantics
1977         // of autoboxing.  Typically, the library will obtain these values
1978         // from the properties set by the VM.  If the properties are for
1979         // internal implementation use only, these properties should be
1980         // removed from the system properties.
1981         //
1982         // See java.lang.Integer.IntegerCache and the
1983         // VM.saveAndRemoveProperties method for example.
1984         //
1985         // Save a private copy of the system properties object that
1986         // can only be accessed by the internal implementation.  Remove
1987         // certain system properties that are not intended for public access.
1988         VM.saveAndRemoveProperties(props);
1989 
1990         lineSeparator = props.getProperty("line.separator");

1991 
1992         FileInputStream fdIn = new FileInputStream(FileDescriptor.in);
1993         FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out);
1994         FileOutputStream fdErr = new FileOutputStream(FileDescriptor.err);
1995         setIn0(new BufferedInputStream(fdIn));
1996         setOut0(newPrintStream(fdOut, props.getProperty("sun.stdout.encoding")));
1997         setErr0(newPrintStream(fdErr, props.getProperty("sun.stderr.encoding")));
1998 
1999         // Setup Java signal handlers for HUP, TERM, and INT (where available).
2000         Terminator.setup();
2001 
2002         // Initialize any miscellaneous operating system settings that need to be
2003         // set for the class libraries. Currently this is no-op everywhere except
2004         // for Windows where the process-wide error mode is set before the java.io
2005         // classes are used.
2006         VM.initializeOSEnvironment();
2007 
2008         // The main thread is not added to its thread group in the same
2009         // way as other threads; we must do it ourselves here.
2010         Thread current = Thread.currentThread();


< prev index next >