1 /*
   2  * Copyright (c) 1994, 2024, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 package java.lang;
  26 
  27 import java.io.BufferedInputStream;
  28 import java.io.BufferedOutputStream;
  29 import java.io.Console;
  30 import java.io.FileDescriptor;
  31 import java.io.FileInputStream;
  32 import java.io.FileOutputStream;
  33 import java.io.IOException;
  34 import java.io.InputStream;
  35 import java.io.OutputStream;
  36 import java.io.PrintStream;
  37 import java.lang.annotation.Annotation;
  38 import java.lang.foreign.MemorySegment;
  39 import java.lang.invoke.MethodHandle;
  40 import java.lang.invoke.MethodType;
  41 import java.lang.module.ModuleDescriptor;
  42 import java.lang.reflect.Executable;
  43 import java.lang.reflect.Method;
  44 import java.net.URI;
  45 import java.nio.channels.Channel;
  46 import java.nio.channels.spi.SelectorProvider;
  47 import java.nio.charset.CharacterCodingException;
  48 import java.nio.charset.Charset;
  49 import java.security.ProtectionDomain;
  50 import java.util.List;
  51 import java.util.Locale;
  52 import java.util.Map;
  53 import java.util.Objects;
  54 import java.util.Properties;
  55 import java.util.ResourceBundle;
  56 import java.util.Set;
  57 import java.util.concurrent.Executor;
  58 import java.util.concurrent.ScheduledExecutorService;
  59 import java.util.function.Supplier;
  60 import java.util.concurrent.ConcurrentHashMap;
  61 import java.util.stream.Stream;
  62 
  63 import jdk.internal.javac.Restricted;
  64 import jdk.internal.loader.NativeLibraries;
  65 import jdk.internal.logger.LoggerFinderLoader.TemporaryLoggerFinder;
  66 import jdk.internal.misc.Blocker;
  67 import jdk.internal.misc.CarrierThreadLocal;
  68 import jdk.internal.util.StaticProperty;
  69 import jdk.internal.module.ModuleBootstrap;
  70 import jdk.internal.module.ServicesCatalog;
  71 import jdk.internal.reflect.CallerSensitive;
  72 import jdk.internal.reflect.Reflection;
  73 import jdk.internal.access.JavaLangAccess;
  74 import jdk.internal.access.SharedSecrets;
  75 import jdk.internal.logger.LoggerFinderLoader;
  76 import jdk.internal.logger.LazyLoggers;
  77 import jdk.internal.logger.LocalizedLoggerWrapper;
  78 import jdk.internal.misc.VM;
  79 import jdk.internal.util.SystemProps;
  80 import jdk.internal.vm.Continuation;
  81 import jdk.internal.vm.ContinuationScope;
  82 import jdk.internal.vm.StackableScope;
  83 import jdk.internal.vm.ThreadContainer;
  84 import jdk.internal.vm.annotation.IntrinsicCandidate;
  85 import jdk.internal.vm.annotation.Stable;
  86 import sun.reflect.annotation.AnnotationType;
  87 import sun.nio.ch.Interruptible;
  88 import sun.nio.cs.UTF_8;
  89 
  90 /**
  91  * The {@code System} class contains several useful class fields
  92  * and methods. It cannot be instantiated.
  93  *
  94  * Among the facilities provided by the {@code System} class
  95  * are standard input, standard output, and error output streams;
  96  * access to externally defined properties and environment
  97  * variables; a means of loading files and libraries; and a utility
  98  * method for quickly copying a portion of an array.
  99  *
 100  * @since   1.0
 101  */
 102 public final class System {
 103     /* Register the natives via the static initializer.
 104      *
 105      * The VM will invoke the initPhase1 method to complete the initialization
 106      * of this class separate from <clinit>.
 107      */
 108     private static native void registerNatives();
 109     static {
 110         registerNatives();
 111     }
 112 
 113     /** Don't let anyone instantiate this class */
 114     private System() {
 115     }
 116 
 117     /**
 118      * The "standard" input stream. This stream is already
 119      * open and ready to supply input data. Typically this stream
 120      * corresponds to keyboard input or another input source specified by
 121      * the host environment or user. In case this stream is wrapped
 122      * in a {@link java.io.InputStreamReader}, {@link Console#charset()}
 123      * should be used for the charset, or consider using
 124      * {@link Console#reader()}.
 125      *
 126      * @see Console#charset()
 127      * @see Console#reader()
 128      */
 129     public static final InputStream in = null;
 130 
 131     /**
 132      * The "standard" output stream. This stream is already
 133      * open and ready to accept output data. Typically this stream
 134      * corresponds to display output or another output destination
 135      * specified by the host environment or user. The encoding used
 136      * in the conversion from characters to bytes is equivalent to
 137      * {@link ##stdout.encoding stdout.encoding}.
 138      * <p>
 139      * For simple stand-alone Java applications, a typical way to write
 140      * a line of output data is:
 141      * <blockquote><pre>
 142      *     System.out.println(data)
 143      * </pre></blockquote>
 144      * <p>
 145      * See the {@code println} methods in class {@code PrintStream}.
 146      *
 147      * @see     java.io.PrintStream#println()
 148      * @see     java.io.PrintStream#println(boolean)
 149      * @see     java.io.PrintStream#println(char)
 150      * @see     java.io.PrintStream#println(char[])
 151      * @see     java.io.PrintStream#println(double)
 152      * @see     java.io.PrintStream#println(float)
 153      * @see     java.io.PrintStream#println(int)
 154      * @see     java.io.PrintStream#println(long)
 155      * @see     java.io.PrintStream#println(java.lang.Object)
 156      * @see     java.io.PrintStream#println(java.lang.String)
 157      * @see     ##stdout.encoding stdout.encoding
 158      */
 159     public static final PrintStream out = null;
 160 
 161     /**
 162      * The "standard" error output stream. This stream is already
 163      * open and ready to accept output data.
 164      * <p>
 165      * Typically this stream corresponds to display output or another
 166      * output destination specified by the host environment or user. By
 167      * convention, this output stream is used to display error messages
 168      * or other information that should come to the immediate attention
 169      * of a user even if the principal output stream, the value of the
 170      * variable {@code out}, has been redirected to a file or other
 171      * destination that is typically not continuously monitored.
 172      * The encoding used in the conversion from characters to bytes is
 173      * equivalent to {@link ##stderr.encoding stderr.encoding}.
 174      *
 175      * @see     ##stderr.encoding stderr.encoding
 176      */
 177     public static final PrintStream err = null;
 178 
 179     // Initial values of System.in and System.err, set in initPhase1().
 180     private static @Stable InputStream initialIn;
 181     private static @Stable PrintStream initialErr;
 182 
 183     // `sun.jnu.encoding` if it is not supported. Otherwise null.
 184     // It is initialized in `initPhase1()` before any charset providers
 185     // are initialized.
 186     private static String notSupportedJnuEncoding;
 187 
 188     /**
 189      * Reassigns the "standard" input stream.
 190      *
 191      * @param in the new standard input stream.
 192      *
 193      * @since   1.1
 194      */
 195     public static void setIn(InputStream in) {
 196         setIn0(in);
 197     }
 198 
 199     /**
 200      * Reassigns the "standard" output stream.
 201      *
 202      * @param out the new standard output stream
 203      *
 204      * @since   1.1
 205      */
 206     public static void setOut(PrintStream out) {
 207         setOut0(out);
 208     }
 209 
 210     /**
 211      * Reassigns the "standard" error output stream.
 212      *
 213      * @param err the new standard error output stream.
 214      *
 215      * @since   1.1
 216      */
 217     public static void setErr(PrintStream err) {
 218         setErr0(err);
 219     }
 220 
 221     private static volatile Console cons;
 222 
 223     /**
 224      * Returns the unique {@link java.io.Console Console} object associated
 225      * with the current Java virtual machine, if any.
 226      *
 227      * @return  The system console, if any, otherwise {@code null}.
 228      *
 229      * @since   1.6
 230      */
 231      public static Console console() {
 232          Console c;
 233          if ((c = cons) == null) {
 234              synchronized (System.class) {
 235                  if ((c = cons) == null) {
 236                      cons = c = SharedSecrets.getJavaIOAccess().console();
 237                  }
 238              }
 239          }
 240          return c;
 241      }
 242 
 243     /**
 244      * Returns the channel inherited from the entity that created this
 245      * Java virtual machine.
 246      *
 247      * This method returns the channel obtained by invoking the
 248      * {@link java.nio.channels.spi.SelectorProvider#inheritedChannel
 249      * inheritedChannel} method of the system-wide default
 250      * {@link java.nio.channels.spi.SelectorProvider} object.
 251      *
 252      * <p> In addition to the network-oriented channels described in
 253      * {@link java.nio.channels.spi.SelectorProvider#inheritedChannel
 254      * inheritedChannel}, this method may return other kinds of
 255      * channels in the future.
 256      *
 257      * @return  The inherited channel, if any, otherwise {@code null}.
 258      *
 259      * @throws  IOException
 260      *          If an I/O error occurs
 261      *
 262      * @since 1.5
 263      */
 264     public static Channel inheritedChannel() throws IOException {
 265         return SelectorProvider.provider().inheritedChannel();
 266     }
 267 
 268     private static native void setIn0(InputStream in);
 269     private static native void setOut0(PrintStream out);
 270     private static native void setErr0(PrintStream err);
 271 
 272     /**
 273      * Throws {@code UnsupportedOperationException}. Setting a security manager
 274      * is not supported.
 275      *
 276      * @param  sm ignored
 277      * @throws UnsupportedOperationException always
 278      * @see #getSecurityManager
 279      * @deprecated This method originally set
 280      *       {@linkplain SecurityManager the system-wide Security Manager}.
 281      *       Setting a Security Manager is no longer supported. There is no
 282      *       replacement for the Security Manager or this method.
 283      */
 284     @Deprecated(since="17", forRemoval=true)
 285     public static void setSecurityManager(@SuppressWarnings("removal") SecurityManager sm) {
 286         throw new UnsupportedOperationException(
 287                  "Setting a Security Manager is not supported");
 288     }
 289 
 290     /**
 291      * Returns {@code null}. Setting a security manager is not supported.
 292      *
 293      * @return  {@code null}
 294      * @see     #setSecurityManager
 295      * @deprecated This method originally returned
 296      *       {@linkplain SecurityManager the system-wide Security Manager}.
 297      *       Setting a Security Manager is no longer supported. There is no
 298      *       replacement for the Security Manager or this method.
 299      */
 300     @SuppressWarnings("removal")
 301     @Deprecated(since="17", forRemoval=true)
 302     public static SecurityManager getSecurityManager() {
 303         return null;
 304     }
 305 
 306     /**
 307      * Returns the current time in milliseconds.  Note that
 308      * while the unit of time of the return value is a millisecond,
 309      * the granularity of the value depends on the underlying
 310      * operating system and may be larger.  For example, many
 311      * operating systems measure time in units of tens of
 312      * milliseconds.
 313      *
 314      * <p> See the description of the class {@code Date} for
 315      * a discussion of slight discrepancies that may arise between
 316      * "computer time" and coordinated universal time (UTC).
 317      *
 318      * @return  the difference, measured in milliseconds, between
 319      *          the current time and midnight, January 1, 1970 UTC.
 320      * @see     java.util.Date
 321      */
 322     @IntrinsicCandidate
 323     public static native long currentTimeMillis();
 324 
 325     /**
 326      * Returns the current value of the running Java Virtual Machine's
 327      * high-resolution time source, in nanoseconds.
 328      *
 329      * This method can only be used to measure elapsed time and is
 330      * not related to any other notion of system or wall-clock time.
 331      * The value returned represents nanoseconds since some fixed but
 332      * arbitrary <i>origin</i> time (perhaps in the future, so values
 333      * may be negative).  The same origin is used by all invocations of
 334      * this method in an instance of a Java virtual machine; other
 335      * virtual machine instances are likely to use a different origin.
 336      *
 337      * <p>This method provides nanosecond precision, but not necessarily
 338      * nanosecond resolution (that is, how frequently the value changes)
 339      * - no guarantees are made except that the resolution is at least as
 340      * good as that of {@link #currentTimeMillis()}.
 341      *
 342      * <p>Differences in successive calls that span greater than
 343      * approximately 292 years (2<sup>63</sup> nanoseconds) will not
 344      * correctly compute elapsed time due to numerical overflow.
 345      *
 346      * <p>The values returned by this method become meaningful only when
 347      * the difference between two such values, obtained within the same
 348      * instance of a Java virtual machine, is computed.
 349      *
 350      * <p>For example, to measure how long some code takes to execute:
 351      * <pre> {@code
 352      * long startTime = System.nanoTime();
 353      * // ... the code being measured ...
 354      * long elapsedNanos = System.nanoTime() - startTime;}</pre>
 355      *
 356      * <p>To compare elapsed time against a timeout, use <pre> {@code
 357      * if (System.nanoTime() - startTime >= timeoutNanos) ...}</pre>
 358      * instead of <pre> {@code
 359      * if (System.nanoTime() >= startTime + timeoutNanos) ...}</pre>
 360      * because of the possibility of numerical overflow.
 361      *
 362      * @return the current value of the running Java Virtual Machine's
 363      *         high-resolution time source, in nanoseconds
 364      * @since 1.5
 365      */
 366     @IntrinsicCandidate
 367     public static native long nanoTime();
 368 
 369     /**
 370      * Copies an array from the specified source array, beginning at the
 371      * specified position, to the specified position of the destination array.
 372      * A subsequence of array components are copied from the source
 373      * array referenced by {@code src} to the destination array
 374      * referenced by {@code dest}. The number of components copied is
 375      * equal to the {@code length} argument. The components at
 376      * positions {@code srcPos} through
 377      * {@code srcPos+length-1} in the source array are copied into
 378      * positions {@code destPos} through
 379      * {@code destPos+length-1}, respectively, of the destination
 380      * array.
 381      * <p>
 382      * If the {@code src} and {@code dest} arguments refer to the
 383      * same array object, then the copying is performed as if the
 384      * components at positions {@code srcPos} through
 385      * {@code srcPos+length-1} were first copied to a temporary
 386      * array with {@code length} components and then the contents of
 387      * the temporary array were copied into positions
 388      * {@code destPos} through {@code destPos+length-1} of the
 389      * destination array.
 390      * <p>
 391      * If {@code dest} is {@code null}, then a
 392      * {@code NullPointerException} is thrown.
 393      * <p>
 394      * If {@code src} is {@code null}, then a
 395      * {@code NullPointerException} is thrown and the destination
 396      * array is not modified.
 397      * <p>
 398      * Otherwise, if any of the following is true, an
 399      * {@code ArrayStoreException} is thrown and the destination is
 400      * not modified:
 401      * <ul>
 402      * <li>The {@code src} argument refers to an object that is not an
 403      *     array.
 404      * <li>The {@code dest} argument refers to an object that is not an
 405      *     array.
 406      * <li>The {@code src} argument and {@code dest} argument refer
 407      *     to arrays whose component types are different primitive types.
 408      * <li>The {@code src} argument refers to an array with a primitive
 409      *    component type and the {@code dest} argument refers to an array
 410      *     with a reference component type.
 411      * <li>The {@code src} argument refers to an array with a reference
 412      *    component type and the {@code dest} argument refers to an array
 413      *     with a primitive component type.
 414      * </ul>
 415      * <p>
 416      * Otherwise, if any of the following is true, an
 417      * {@code IndexOutOfBoundsException} is
 418      * thrown and the destination is not modified:
 419      * <ul>
 420      * <li>The {@code srcPos} argument is negative.
 421      * <li>The {@code destPos} argument is negative.
 422      * <li>The {@code length} argument is negative.
 423      * <li>{@code srcPos+length} is greater than
 424      *     {@code src.length}, the length of the source array.
 425      * <li>{@code destPos+length} is greater than
 426      *     {@code dest.length}, the length of the destination array.
 427      * </ul>
 428      * <p>
 429      * Otherwise, if any actual component of the source array from
 430      * position {@code srcPos} through
 431      * {@code srcPos+length-1} cannot be converted to the component
 432      * type of the destination array by assignment conversion, an
 433      * {@code ArrayStoreException} is thrown. In this case, let
 434      * <b><i>k</i></b> be the smallest nonnegative integer less than
 435      * length such that {@code src[srcPos+}<i>k</i>{@code ]}
 436      * cannot be converted to the component type of the destination
 437      * array; when the exception is thrown, source array components from
 438      * positions {@code srcPos} through
 439      * {@code srcPos+}<i>k</i>{@code -1}
 440      * will already have been copied to destination array positions
 441      * {@code destPos} through
 442      * {@code destPos+}<i>k</I>{@code -1} and no other
 443      * positions of the destination array will have been modified.
 444      * (Because of the restrictions already itemized, this
 445      * paragraph effectively applies only to the situation where both
 446      * arrays have component types that are reference types.)
 447      *
 448      * @param      src      the source array.
 449      * @param      srcPos   starting position in the source array.
 450      * @param      dest     the destination array.
 451      * @param      destPos  starting position in the destination data.
 452      * @param      length   the number of array elements to be copied.
 453      * @throws     IndexOutOfBoundsException  if copying would cause
 454      *             access of data outside array bounds.
 455      * @throws     ArrayStoreException  if an element in the {@code src}
 456      *             array could not be stored into the {@code dest} array
 457      *             because of a type mismatch.
 458      * @throws     NullPointerException if either {@code src} or
 459      *             {@code dest} is {@code null}.
 460      */
 461     @IntrinsicCandidate
 462     public static native void arraycopy(Object src,  int  srcPos,
 463                                         Object dest, int destPos,
 464                                         int length);
 465 
 466     /**
 467      * Returns the same hash code for the given object as
 468      * would be returned by the default method hashCode(),
 469      * whether or not the given object's class overrides
 470      * hashCode().
 471      * The hash code for the null reference is zero.
 472      *
 473      * @param x object for which the hashCode is to be calculated
 474      * @return  the hashCode
 475      * @since   1.1
 476      * @see Object#hashCode
 477      * @see java.util.Objects#hashCode(Object)
 478      */
 479     @IntrinsicCandidate
 480     public static native int identityHashCode(Object x);
 481 
 482     /**
 483      * System properties.
 484      *
 485      * See {@linkplain #getProperties getProperties} for details.
 486      */
 487     private static Properties props;
 488 
 489     /**
 490      * Determines the current system properties.
 491      * <p>
 492      * The current set of system properties for use by the
 493      * {@link #getProperty(String)} method is returned as a
 494      * {@code Properties} object. If there is no current set of
 495      * system properties, a set of system properties is first created and
 496      * initialized. This set of system properties includes a value
 497      * for each of the following keys unless the description of the associated
 498      * value indicates that the value is optional.
 499      * <table class="striped" style="text-align:left">
 500      * <caption style="display:none">Shows property keys and associated values</caption>
 501      * <thead>
 502      * <tr><th scope="col">Key</th>
 503      *     <th scope="col">Description of Associated Value</th></tr>
 504      * </thead>
 505      * <tbody>
 506      * <tr><th scope="row">{@systemProperty java.version}</th>
 507      *     <td>Java Runtime Environment version, which may be interpreted
 508      *     as a {@link Runtime.Version}</td></tr>
 509      * <tr><th scope="row">{@systemProperty java.version.date}</th>
 510      *     <td>Java Runtime Environment version date, in ISO-8601 YYYY-MM-DD
 511      *     format, which may be interpreted as a {@link
 512      *     java.time.LocalDate}</td></tr>
 513      * <tr><th scope="row">{@systemProperty java.vendor}</th>
 514      *     <td>Java Runtime Environment vendor</td></tr>
 515      * <tr><th scope="row">{@systemProperty java.vendor.url}</th>
 516      *     <td>Java vendor URL</td></tr>
 517      * <tr><th scope="row">{@systemProperty java.vendor.version}</th>
 518      *     <td>Java vendor version <em>(optional)</em> </td></tr>
 519      * <tr><th scope="row">{@systemProperty java.home}</th>
 520      *     <td>Java installation directory</td></tr>
 521      * <tr><th scope="row">{@systemProperty java.vm.specification.version}</th>
 522      *     <td>Java Virtual Machine specification version, whose value is the
 523      *     {@linkplain Runtime.Version#feature feature} element of the
 524      *     {@linkplain Runtime#version() runtime version}</td></tr>
 525      * <tr><th scope="row">{@systemProperty java.vm.specification.vendor}</th>
 526      *     <td>Java Virtual Machine specification vendor</td></tr>
 527      * <tr><th scope="row">{@systemProperty java.vm.specification.name}</th>
 528      *     <td>Java Virtual Machine specification name</td></tr>
 529      * <tr><th scope="row">{@systemProperty java.vm.version}</th>
 530      *     <td>Java Virtual Machine implementation version which may be
 531      *     interpreted as a {@link Runtime.Version}</td></tr>
 532      * <tr><th scope="row">{@systemProperty java.vm.vendor}</th>
 533      *     <td>Java Virtual Machine implementation vendor</td></tr>
 534      * <tr><th scope="row">{@systemProperty java.vm.name}</th>
 535      *     <td>Java Virtual Machine implementation name</td></tr>
 536      * <tr><th scope="row">{@systemProperty java.specification.version}</th>
 537      *     <td>Java Runtime Environment specification version, whose value is
 538      *     the {@linkplain Runtime.Version#feature feature} element of the
 539      *     {@linkplain Runtime#version() runtime version}</td></tr>
 540      * <tr><th scope="row">{@systemProperty java.specification.maintenance.version}</th>
 541      *     <td>Java Runtime Environment specification maintenance version,
 542      *     may be interpreted as a positive integer <em>(optional, see below)</em></td></tr>
 543      * <tr><th scope="row">{@systemProperty java.specification.vendor}</th>
 544      *     <td>Java Runtime Environment specification  vendor</td></tr>
 545      * <tr><th scope="row">{@systemProperty java.specification.name}</th>
 546      *     <td>Java Runtime Environment specification  name</td></tr>
 547      * <tr><th scope="row">{@systemProperty java.class.version}</th>
 548      *     <td>{@linkplain java.lang.reflect.ClassFileFormatVersion#latest() Latest}
 549      *     Java class file format version recognized by the Java runtime as {@code "MAJOR.MINOR"}
 550      *     where {@link java.lang.reflect.ClassFileFormatVersion#major() MAJOR} and {@code MINOR}
 551      *     are both formatted as decimal integers</td></tr>
 552      * <tr><th scope="row">{@systemProperty java.class.path}</th>
 553      *     <td>Java class path  (refer to
 554      *        {@link ClassLoader#getSystemClassLoader()} for details)</td></tr>
 555      * <tr><th scope="row">{@systemProperty java.library.path}</th>
 556      *     <td>List of paths to search when loading libraries</td></tr>
 557      * <tr><th scope="row">{@systemProperty java.io.tmpdir}</th>
 558      *     <td>Default temp file path</td></tr>
 559      * <tr><th scope="row">{@systemProperty os.name}</th>
 560      *     <td>Operating system name</td></tr>
 561      * <tr><th scope="row">{@systemProperty os.arch}</th>
 562      *     <td>Operating system architecture</td></tr>
 563      * <tr><th scope="row">{@systemProperty os.version}</th>
 564      *     <td>Operating system version</td></tr>
 565      * <tr><th scope="row">{@systemProperty file.separator}</th>
 566      *     <td>File separator ("/" on UNIX)</td></tr>
 567      * <tr><th scope="row">{@systemProperty path.separator}</th>
 568      *     <td>Path separator (":" on UNIX)</td></tr>
 569      * <tr><th scope="row">{@systemProperty line.separator}</th>
 570      *     <td>Line separator ("\n" on UNIX)</td></tr>
 571      * <tr><th scope="row">{@systemProperty user.name}</th>
 572      *     <td>User's account name</td></tr>
 573      * <tr><th scope="row">{@systemProperty user.home}</th>
 574      *     <td>User's home directory</td></tr>
 575      * <tr><th scope="row">{@systemProperty user.dir}</th>
 576      *     <td>User's current working directory</td></tr>
 577      * <tr><th scope="row">{@systemProperty native.encoding}</th>
 578      *     <td>Character encoding name derived from the host environment and/or
 579      *     the user's settings. Setting this system property has no effect.</td></tr>
 580      * <tr><th scope="row">{@systemProperty stdout.encoding}</th>
 581      *     <td>Character encoding name for {@link System#out System.out} and
 582      *     {@link System#console() System.console()}.
 583      *     The Java runtime can be started with the system property set to {@code UTF-8},
 584      *     starting it with the property set to another value leads to undefined behavior.
 585      * <tr><th scope="row">{@systemProperty stderr.encoding}</th>
 586      *     <td>Character encoding name for {@link System#err System.err}.
 587      *     The Java runtime can be started with the system property set to {@code UTF-8},
 588      *     starting it with the property set to another value leads to undefined behavior.
 589      * </tbody>
 590      * </table>
 591      * <p>
 592      * The {@code java.specification.maintenance.version} property is
 593      * defined if the specification implemented by this runtime at the
 594      * time of its construction had undergone a <a
 595      * href="https://jcp.org/en/procedures/jcp2#3.6.4">maintenance
 596      * release</a>. When defined, its value identifies that
 597      * maintenance release. To indicate the first maintenance release
 598      * this property will have the value {@code "1"}, to indicate the
 599      * second maintenance release this property will have the value
 600      * {@code "2"}, and so on.
 601      * <p>
 602      * Multiple paths in a system property value are separated by the path
 603      * separator character of the platform.
 604      * <p>
 605      * Additional locale-related system properties defined by the
 606      * {@link Locale##default_locale Default Locale} section in the {@code Locale}
 607      * class description may also be obtained with this method.
 608      *
 609      * @apiNote
 610      * <strong>Changing a standard system property may have unpredictable results
 611      * unless otherwise specified.</strong>
 612      * Property values may be cached during initialization or on first use.
 613      * Setting a standard property after initialization using {@link #getProperties()},
 614      * {@link #setProperties(Properties)}, {@link #setProperty(String, String)}, or
 615      * {@link #clearProperty(String)} may not have the desired effect.
 616      *
 617      * @implNote
 618      * In addition to the standard system properties, the system
 619      * properties may include the following keys:
 620      * <table class="striped">
 621      * <caption style="display:none">Shows property keys and associated values</caption>
 622      * <thead>
 623      * <tr><th scope="col">Key</th>
 624      *     <th scope="col">Description of Associated Value</th></tr>
 625      * </thead>
 626      * <tbody>
 627      * <tr><th scope="row">{@systemProperty jdk.module.path}</th>
 628      *     <td>The application module path</td></tr>
 629      * <tr><th scope="row">{@systemProperty jdk.module.upgrade.path}</th>
 630      *     <td>The upgrade module path</td></tr>
 631      * <tr><th scope="row">{@systemProperty jdk.module.main}</th>
 632      *     <td>The module name of the initial/main module</td></tr>
 633      * <tr><th scope="row">{@systemProperty jdk.module.main.class}</th>
 634      *     <td>The main class name of the initial module</td></tr>
 635      * <tr><th scope="row">{@systemProperty file.encoding}</th>
 636      *     <td>The name of the default charset, defaults to {@code UTF-8}.
 637      *     The property may be set on the command line to the value
 638      *     {@code UTF-8} or {@code COMPAT}. If set on the command line to
 639      *     the value {@code COMPAT} then the value is replaced with the
 640      *     value of the {@code native.encoding} property during startup.
 641      *     Setting the property to a value other than {@code UTF-8} or
 642      *     {@code COMPAT} leads to unspecified behavior.
 643      *     </td></tr>
 644      * </tbody>
 645      * </table>
 646      *
 647      * @return     the system properties
 648      * @see        #setProperties
 649      * @see        java.util.Properties
 650      */
 651     public static Properties getProperties() {
 652         return props;
 653     }
 654 
 655     /**
 656      * Returns the system-dependent line separator string.  It always
 657      * returns the same value - the initial value of the {@linkplain
 658      * #getProperty(String) system property} {@code line.separator}.
 659      *
 660      * <p>On UNIX systems, it returns {@code "\n"}; on Microsoft
 661      * Windows systems it returns {@code "\r\n"}.
 662      *
 663      * @return the system-dependent line separator string
 664      * @since 1.7
 665      */
 666     public static String lineSeparator() {
 667         return lineSeparator;
 668     }
 669 
 670     private static String lineSeparator;
 671 
 672     /**
 673      * Sets the system properties to the {@code Properties} argument.
 674      * <p>
 675      * The argument becomes the current set of system properties for use
 676      * by the {@link #getProperty(String)} method. If the argument is
 677      * {@code null}, then the current set of system properties is
 678      * forgotten.
 679      *
 680      * @apiNote
 681      * <strong>Changing a standard system property may have unpredictable results
 682      * unless otherwise specified</strong>.
 683      * See {@linkplain #getProperties getProperties} for details.
 684      *
 685      * @param      props   the new system properties.
 686      * @see        #getProperties
 687      * @see        java.util.Properties
 688      */
 689     public static void setProperties(Properties props) {
 690         if (props == null) {
 691             Map<String, String> tempProps = SystemProps.initProperties();
 692             VersionProps.init(tempProps);
 693             props = createProperties(tempProps);
 694         }
 695         System.props = props;
 696     }
 697 
 698     /**
 699      * Gets the system property indicated by the specified key.
 700      * <p>
 701      * If there is no current set of system properties, a set of system
 702      * properties is first created and initialized in the same manner as
 703      * for the {@code getProperties} method.
 704      *
 705      * @apiNote
 706      * <strong>Changing a standard system property may have unpredictable results
 707      * unless otherwise specified</strong>.
 708      * See {@linkplain #getProperties getProperties} for details.
 709      *
 710      * @param      key   the name of the system property.
 711      * @return     the string value of the system property,
 712      *             or {@code null} if there is no property with that key.
 713      *
 714      * @throws     NullPointerException if {@code key} is {@code null}.
 715      * @throws     IllegalArgumentException if {@code key} is empty.
 716      * @see        #setProperty
 717      * @see        java.lang.System#getProperties()
 718      */
 719     public static String getProperty(String key) {
 720         checkKey(key);
 721         return props.getProperty(key);
 722     }
 723 
 724     /**
 725      * Gets the system property indicated by the specified key.
 726      * <p>
 727      * If there is no current set of system properties, a set of system
 728      * properties is first created and initialized in the same manner as
 729      * for the {@code getProperties} method.
 730      *
 731      * @param      key   the name of the system property.
 732      * @param      def   a default value.
 733      * @return     the string value of the system property,
 734      *             or the default value if there is no property with that key.
 735      *
 736      * @throws     NullPointerException if {@code key} is {@code null}.
 737      * @throws     IllegalArgumentException if {@code key} is empty.
 738      * @see        #setProperty
 739      * @see        java.lang.System#getProperties()
 740      */
 741     public static String getProperty(String key, String def) {
 742         checkKey(key);
 743         return props.getProperty(key, def);
 744     }
 745 
 746     /**
 747      * Sets the system property indicated by the specified key.
 748      *
 749      * @apiNote
 750      * <strong>Changing a standard system property may have unpredictable results
 751      * unless otherwise specified</strong>.
 752      * See {@linkplain #getProperties getProperties} for details.
 753      *
 754      * @param      key   the name of the system property.
 755      * @param      value the value of the system property.
 756      * @return     the previous value of the system property,
 757      *             or {@code null} if it did not have one.
 758      *
 759      * @throws     NullPointerException if {@code key} or
 760      *             {@code value} is {@code null}.
 761      * @throws     IllegalArgumentException if {@code key} is empty.
 762      * @see        #getProperty
 763      * @see        java.lang.System#getProperty(java.lang.String)
 764      * @see        java.lang.System#getProperty(java.lang.String, java.lang.String)
 765      * @since      1.2
 766      */
 767     public static String setProperty(String key, String value) {
 768         checkKey(key);
 769         return (String) props.setProperty(key, value);
 770     }
 771 
 772     /**
 773      * Removes the system property indicated by the specified key.
 774      *
 775      * @apiNote
 776      * <strong>Changing a standard system property may have unpredictable results
 777      * unless otherwise specified</strong>.
 778      * See {@linkplain #getProperties getProperties} method for details.
 779      *
 780      * @param      key   the name of the system property to be removed.
 781      * @return     the previous string value of the system property,
 782      *             or {@code null} if there was no property with that key.
 783      *
 784      * @throws     NullPointerException if {@code key} is {@code null}.
 785      * @throws     IllegalArgumentException if {@code key} is empty.
 786      * @see        #getProperty
 787      * @see        #setProperty
 788      * @see        java.util.Properties
 789      * @since 1.5
 790      */
 791     public static String clearProperty(String key) {
 792         checkKey(key);
 793         return (String) props.remove(key);
 794     }
 795 
 796     private static void checkKey(String key) {
 797         if (key == null) {
 798             throw new NullPointerException("key can't be null");
 799         }
 800         if (key.isEmpty()) {
 801             throw new IllegalArgumentException("key can't be empty");
 802         }
 803     }
 804 
 805     /**
 806      * Gets the value of the specified environment variable. An
 807      * environment variable is a system-dependent external named
 808      * value.
 809      *
 810      * <p><a id="EnvironmentVSSystemProperties"><i>System
 811      * properties</i> and <i>environment variables</i></a> are both
 812      * conceptually mappings between names and values.  Both
 813      * mechanisms can be used to pass user-defined information to a
 814      * Java process.  Environment variables have a more global effect,
 815      * because they are visible to all descendants of the process
 816      * which defines them, not just the immediate Java subprocess.
 817      * They can have subtly different semantics, such as case
 818      * insensitivity, on different operating systems.  For these
 819      * reasons, environment variables are more likely to have
 820      * unintended side effects.  It is best to use system properties
 821      * where possible.  Environment variables should be used when a
 822      * global effect is desired, or when an external system interface
 823      * requires an environment variable (such as {@code PATH}).
 824      *
 825      * <p>On UNIX systems the alphabetic case of {@code name} is
 826      * typically significant, while on Microsoft Windows systems it is
 827      * typically not.  For example, the expression
 828      * {@code System.getenv("FOO").equals(System.getenv("foo"))}
 829      * is likely to be true on Microsoft Windows.
 830      *
 831      * @param  name the name of the environment variable
 832      * @return the string value of the variable, or {@code null}
 833      *         if the variable is not defined in the system environment
 834      * @throws NullPointerException if {@code name} is {@code null}
 835      * @see    #getenv()
 836      * @see    ProcessBuilder#environment()
 837      */
 838     public static String getenv(String name) {
 839         return ProcessEnvironment.getenv(name);
 840     }
 841 
 842 
 843     /**
 844      * Returns an unmodifiable string map view of the current system environment.
 845      * The environment is a system-dependent mapping from names to
 846      * values which is passed from parent to child processes.
 847      *
 848      * <p>If the system does not support environment variables, an
 849      * empty map is returned.
 850      *
 851      * <p>The returned map will never contain null keys or values.
 852      * Attempting to query the presence of a null key or value will
 853      * throw a {@link NullPointerException}.  Attempting to query
 854      * the presence of a key or value which is not of type
 855      * {@link String} will throw a {@link ClassCastException}.
 856      *
 857      * <p>The returned map and its collection views may not obey the
 858      * general contract of the {@link Object#equals} and
 859      * {@link Object#hashCode} methods.
 860      *
 861      * <p>The returned map is typically case-sensitive on all platforms.
 862      *
 863      * <p>When passing information to a Java subprocess,
 864      * <a href=#EnvironmentVSSystemProperties>system properties</a>
 865      * are generally preferred over environment variables.
 866      *
 867      * @return the environment as a map of variable names to values
 868      * @see    #getenv(String)
 869      * @see    ProcessBuilder#environment()
 870      * @since  1.5
 871      */
 872     public static java.util.Map<String,String> getenv() {
 873         return ProcessEnvironment.getenv();
 874     }
 875 
 876     /**
 877      * {@code System.Logger} instances log messages that will be
 878      * routed to the underlying logging framework the {@link System.LoggerFinder
 879      * LoggerFinder} uses.
 880      *
 881      * {@code System.Logger} instances are typically obtained from
 882      * the {@link java.lang.System System} class, by calling
 883      * {@link java.lang.System#getLogger(java.lang.String) System.getLogger(loggerName)}
 884      * or {@link java.lang.System#getLogger(java.lang.String, java.util.ResourceBundle)
 885      * System.getLogger(loggerName, bundle)}.
 886      *
 887      * @see java.lang.System#getLogger(java.lang.String)
 888      * @see java.lang.System#getLogger(java.lang.String, java.util.ResourceBundle)
 889      * @see java.lang.System.LoggerFinder
 890      *
 891      * @since 9
 892      */
 893     public interface Logger {
 894 
 895         /**
 896          * System {@linkplain Logger loggers} levels.
 897          *
 898          * A level has a {@linkplain #getName() name} and {@linkplain
 899          * #getSeverity() severity}.
 900          * Level values are {@link #ALL}, {@link #TRACE}, {@link #DEBUG},
 901          * {@link #INFO}, {@link #WARNING}, {@link #ERROR}, {@link #OFF},
 902          * by order of increasing severity.
 903          * <br>
 904          * {@link #ALL} and {@link #OFF}
 905          * are simple markers with severities mapped respectively to
 906          * {@link java.lang.Integer#MIN_VALUE Integer.MIN_VALUE} and
 907          * {@link java.lang.Integer#MAX_VALUE Integer.MAX_VALUE}.
 908          * <p>
 909          * <b>Severity values and Mapping to {@code java.util.logging.Level}.</b>
 910          * <p>
 911          * {@linkplain System.Logger.Level System logger levels} are mapped to
 912          * {@linkplain java.logging/java.util.logging.Level  java.util.logging levels}
 913          * of corresponding severity.
 914          * <br>The mapping is as follows:
 915          * <br><br>
 916          * <table class="striped">
 917          * <caption>System.Logger Severity Level Mapping</caption>
 918          * <thead>
 919          * <tr><th scope="col">System.Logger Levels</th>
 920          *     <th scope="col">java.util.logging Levels</th>
 921          * </thead>
 922          * <tbody>
 923          * <tr><th scope="row">{@link Logger.Level#ALL ALL}</th>
 924          *     <td>{@link java.logging/java.util.logging.Level#ALL ALL}</td>
 925          * <tr><th scope="row">{@link Logger.Level#TRACE TRACE}</th>
 926          *     <td>{@link java.logging/java.util.logging.Level#FINER FINER}</td>
 927          * <tr><th scope="row">{@link Logger.Level#DEBUG DEBUG}</th>
 928          *     <td>{@link java.logging/java.util.logging.Level#FINE FINE}</td>
 929          * <tr><th scope="row">{@link Logger.Level#INFO INFO}</th>
 930          *     <td>{@link java.logging/java.util.logging.Level#INFO INFO}</td>
 931          * <tr><th scope="row">{@link Logger.Level#WARNING WARNING}</th>
 932          *     <td>{@link java.logging/java.util.logging.Level#WARNING WARNING}</td>
 933          * <tr><th scope="row">{@link Logger.Level#ERROR ERROR}</th>
 934          *     <td>{@link java.logging/java.util.logging.Level#SEVERE SEVERE}</td>
 935          * <tr><th scope="row">{@link Logger.Level#OFF OFF}</th>
 936          *     <td>{@link java.logging/java.util.logging.Level#OFF OFF}</td>
 937          * </tbody>
 938          * </table>
 939          *
 940          * @since 9
 941          *
 942          * @see java.lang.System.LoggerFinder
 943          * @see java.lang.System.Logger
 944          */
 945         @SuppressWarnings("doclint:reference") // cross-module links
 946         public enum Level {
 947 
 948             // for convenience, we're reusing java.util.logging.Level int values
 949             // the mapping logic in sun.util.logging.PlatformLogger depends
 950             // on this.
 951             /**
 952              * A marker to indicate that all levels are enabled.
 953              * This level {@linkplain #getSeverity() severity} is
 954              * {@link Integer#MIN_VALUE}.
 955              */
 956             ALL(Integer.MIN_VALUE),  // typically mapped to/from j.u.l.Level.ALL
 957             /**
 958              * {@code TRACE} level: usually used to log diagnostic information.
 959              * This level {@linkplain #getSeverity() severity} is
 960              * {@code 400}.
 961              */
 962             TRACE(400),   // typically mapped to/from j.u.l.Level.FINER
 963             /**
 964              * {@code DEBUG} level: usually used to log debug information traces.
 965              * This level {@linkplain #getSeverity() severity} is
 966              * {@code 500}.
 967              */
 968             DEBUG(500),   // typically mapped to/from j.u.l.Level.FINEST/FINE/CONFIG
 969             /**
 970              * {@code INFO} level: usually used to log information messages.
 971              * This level {@linkplain #getSeverity() severity} is
 972              * {@code 800}.
 973              */
 974             INFO(800),    // typically mapped to/from j.u.l.Level.INFO
 975             /**
 976              * {@code WARNING} level: usually used to log warning messages.
 977              * This level {@linkplain #getSeverity() severity} is
 978              * {@code 900}.
 979              */
 980             WARNING(900), // typically mapped to/from j.u.l.Level.WARNING
 981             /**
 982              * {@code ERROR} level: usually used to log error messages.
 983              * This level {@linkplain #getSeverity() severity} is
 984              * {@code 1000}.
 985              */
 986             ERROR(1000),  // typically mapped to/from j.u.l.Level.SEVERE
 987             /**
 988              * A marker to indicate that all levels are disabled.
 989              * This level {@linkplain #getSeverity() severity} is
 990              * {@link Integer#MAX_VALUE}.
 991              */
 992             OFF(Integer.MAX_VALUE);  // typically mapped to/from j.u.l.Level.OFF
 993 
 994             private final int severity;
 995 
 996             private Level(int severity) {
 997                 this.severity = severity;
 998             }
 999 
1000             /**
1001              * Returns the name of this level.
1002              * @return this level {@linkplain #name()}.
1003              */
1004             public final String getName() {
1005                 return name();
1006             }
1007 
1008             /**
1009              * Returns the severity of this level.
1010              * A higher severity means a more severe condition.
1011              * @return this level severity.
1012              */
1013             public final int getSeverity() {
1014                 return severity;
1015             }
1016         }
1017 
1018         /**
1019          * Returns the name of this logger.
1020          *
1021          * @return the logger name.
1022          */
1023         public String getName();
1024 
1025         /**
1026          * Checks if a message of the given level would be logged by
1027          * this logger.
1028          *
1029          * @param level the log message level.
1030          * @return {@code true} if the given log message level is currently
1031          *         being logged.
1032          *
1033          * @throws NullPointerException if {@code level} is {@code null}.
1034          */
1035         public boolean isLoggable(Level level);
1036 
1037         /**
1038          * Logs a message.
1039          *
1040          * @implSpec The default implementation for this method calls
1041          * {@code this.log(level, (ResourceBundle)null, msg, (Object[])null);}
1042          *
1043          * @param level the log message level.
1044          * @param msg the string message (or a key in the message catalog, if
1045          * this logger is a {@link
1046          * LoggerFinder#getLocalizedLogger(java.lang.String,
1047          * java.util.ResourceBundle, java.lang.Module) localized logger});
1048          * can be {@code null}.
1049          *
1050          * @throws NullPointerException if {@code level} is {@code null}.
1051          */
1052         public default void log(Level level, String msg) {
1053             log(level, (ResourceBundle) null, msg, (Object[]) null);
1054         }
1055 
1056         /**
1057          * Logs a lazily supplied message.
1058          *
1059          * If the logger is currently enabled for the given log message level
1060          * then a message is logged that is the result produced by the
1061          * given supplier function.  Otherwise, the supplier is not operated on.
1062          *
1063          * @implSpec When logging is enabled for the given level, the default
1064          * implementation for this method calls
1065          * {@code this.log(level, (ResourceBundle)null, msgSupplier.get(), (Object[])null);}
1066          *
1067          * @param level the log message level.
1068          * @param msgSupplier a supplier function that produces a message.
1069          *
1070          * @throws NullPointerException if {@code level} is {@code null},
1071          *         or {@code msgSupplier} is {@code null}.
1072          */
1073         public default void log(Level level, Supplier<String> msgSupplier) {
1074             Objects.requireNonNull(msgSupplier);
1075             if (isLoggable(Objects.requireNonNull(level))) {
1076                 log(level, (ResourceBundle) null, msgSupplier.get(), (Object[]) null);
1077             }
1078         }
1079 
1080         /**
1081          * Logs a message produced from the given object.
1082          *
1083          * If the logger is currently enabled for the given log message level then
1084          * a message is logged that, by default, is the result produced from
1085          * calling  toString on the given object.
1086          * Otherwise, the object is not operated on.
1087          *
1088          * @implSpec When logging is enabled for the given level, the default
1089          * implementation for this method calls
1090          * {@code this.log(level, (ResourceBundle)null, obj.toString(), (Object[])null);}
1091          *
1092          * @param level the log message level.
1093          * @param obj the object to log.
1094          *
1095          * @throws NullPointerException if {@code level} is {@code null}, or
1096          *         {@code obj} is {@code null}.
1097          */
1098         public default void log(Level level, Object obj) {
1099             Objects.requireNonNull(obj);
1100             if (isLoggable(Objects.requireNonNull(level))) {
1101                 this.log(level, (ResourceBundle) null, obj.toString(), (Object[]) null);
1102             }
1103         }
1104 
1105         /**
1106          * Logs a message associated with a given throwable.
1107          *
1108          * @implSpec The default implementation for this method calls
1109          * {@code this.log(level, (ResourceBundle)null, msg, thrown);}
1110          *
1111          * @param level the log message level.
1112          * @param msg the string message (or a key in the message catalog, if
1113          * this logger is a {@link
1114          * LoggerFinder#getLocalizedLogger(java.lang.String,
1115          * java.util.ResourceBundle, java.lang.Module) localized logger});
1116          * can be {@code null}.
1117          * @param thrown a {@code Throwable} associated with the log message;
1118          *        can be {@code null}.
1119          *
1120          * @throws NullPointerException if {@code level} is {@code null}.
1121          */
1122         public default void log(Level level, String msg, Throwable thrown) {
1123             this.log(level, null, msg, thrown);
1124         }
1125 
1126         /**
1127          * Logs a lazily supplied message associated with a given throwable.
1128          *
1129          * If the logger is currently enabled for the given log message level
1130          * then a message is logged that is the result produced by the
1131          * given supplier function.  Otherwise, the supplier is not operated on.
1132          *
1133          * @implSpec When logging is enabled for the given level, the default
1134          * implementation for this method calls
1135          * {@code this.log(level, (ResourceBundle)null, msgSupplier.get(), thrown);}
1136          *
1137          * @param level one of the log message level identifiers.
1138          * @param msgSupplier a supplier function that produces a message.
1139          * @param thrown a {@code Throwable} associated with log message;
1140          *               can be {@code null}.
1141          *
1142          * @throws NullPointerException if {@code level} is {@code null}, or
1143          *                               {@code msgSupplier} is {@code null}.
1144          */
1145         public default void log(Level level, Supplier<String> msgSupplier,
1146                 Throwable thrown) {
1147             Objects.requireNonNull(msgSupplier);
1148             if (isLoggable(Objects.requireNonNull(level))) {
1149                 this.log(level, null, msgSupplier.get(), thrown);
1150             }
1151         }
1152 
1153         /**
1154          * Logs a message with an optional list of parameters.
1155          *
1156          * @implSpec The default implementation for this method calls
1157          * {@code this.log(level, (ResourceBundle)null, format, params);}
1158          *
1159          * @param level one of the log message level identifiers.
1160          * @param format the string message format in {@link
1161          * java.text.MessageFormat} format, (or a key in the message
1162          * catalog, if this logger is a {@link
1163          * LoggerFinder#getLocalizedLogger(java.lang.String,
1164          * java.util.ResourceBundle, java.lang.Module) localized logger});
1165          * can be {@code null}.
1166          * @param params an optional list of parameters to the message (may be
1167          * none).
1168          *
1169          * @throws NullPointerException if {@code level} is {@code null}.
1170          */
1171         public default void log(Level level, String format, Object... params) {
1172             this.log(level, null, format, params);
1173         }
1174 
1175         /**
1176          * Logs a localized message associated with a given throwable.
1177          *
1178          * If the given resource bundle is non-{@code null},  the {@code msg}
1179          * string is localized using the given resource bundle.
1180          * Otherwise the {@code msg} string is not localized.
1181          *
1182          * @param level the log message level.
1183          * @param bundle a resource bundle to localize {@code msg}; can be
1184          * {@code null}.
1185          * @param msg the string message (or a key in the message catalog,
1186          *            if {@code bundle} is not {@code null}); can be {@code null}.
1187          * @param thrown a {@code Throwable} associated with the log message;
1188          *        can be {@code null}.
1189          *
1190          * @throws NullPointerException if {@code level} is {@code null}.
1191          */
1192         public void log(Level level, ResourceBundle bundle, String msg,
1193                 Throwable thrown);
1194 
1195         /**
1196          * Logs a message with resource bundle and an optional list of
1197          * parameters.
1198          *
1199          * If the given resource bundle is non-{@code null},  the {@code format}
1200          * string is localized using the given resource bundle.
1201          * Otherwise the {@code format} string is not localized.
1202          *
1203          * @param level the log message level.
1204          * @param bundle a resource bundle to localize {@code format}; can be
1205          * {@code null}.
1206          * @param format the string message format in {@link
1207          * java.text.MessageFormat} format, (or a key in the message
1208          * catalog if {@code bundle} is not {@code null}); can be {@code null}.
1209          * @param params an optional list of parameters to the message (may be
1210          * none).
1211          *
1212          * @throws NullPointerException if {@code level} is {@code null}.
1213          */
1214         public void log(Level level, ResourceBundle bundle, String format,
1215                 Object... params);
1216     }
1217 
1218     /**
1219      * The {@code LoggerFinder} service is responsible for creating, managing,
1220      * and configuring loggers to the underlying framework it uses.
1221      *
1222      * A logger finder is a concrete implementation of this class that has a
1223      * zero-argument constructor and implements the abstract methods defined
1224      * by this class.
1225      * The loggers returned from a logger finder are capable of routing log
1226      * messages to the logging backend this provider supports.
1227      * A given invocation of the Java Runtime maintains a single
1228      * system-wide LoggerFinder instance that is loaded as follows:
1229      * <ul>
1230      *    <li>First it finds any custom {@code LoggerFinder} provider
1231      *        using the {@link java.util.ServiceLoader} facility with the
1232      *        {@linkplain ClassLoader#getSystemClassLoader() system class
1233      *        loader}.</li>
1234      *    <li>If no {@code LoggerFinder} provider is found, the system default
1235      *        {@code LoggerFinder} implementation will be used.</li>
1236      * </ul>
1237      * <p>
1238      * An application can replace the logging backend
1239      * <i>even when the java.logging module is present</i>, by simply providing
1240      * and declaring an implementation of the {@link LoggerFinder} service.
1241      * <p>
1242      * <b>Default Implementation</b>
1243      * <p>
1244      * The system default {@code LoggerFinder} implementation uses
1245      * {@code java.util.logging} as the backend framework when the
1246      * {@code java.logging} module is present.
1247      * It returns a {@linkplain System.Logger logger} instance
1248      * that will route log messages to a {@link java.logging/java.util.logging.Logger
1249      * java.util.logging.Logger}. Otherwise, if {@code java.logging} is not
1250      * present, the default implementation will return a simple logger
1251      * instance that will route log messages of {@code INFO} level and above to
1252      * the console ({@code System.err}).
1253      * <p>
1254      * <b>Logging Configuration</b>
1255      * <p>
1256      * {@linkplain Logger Logger} instances obtained from the
1257      * {@code LoggerFinder} factory methods are not directly configurable by
1258      * the application. Configuration is the responsibility of the underlying
1259      * logging backend, and usually requires using APIs specific to that backend.
1260      * <p>For the default {@code LoggerFinder} implementation
1261      * using {@code java.util.logging} as its backend, refer to
1262      * {@link java.logging/java.util.logging java.util.logging} for logging configuration.
1263      * For the default {@code LoggerFinder} implementation returning simple loggers
1264      * when the {@code java.logging} module is absent, the configuration
1265      * is implementation dependent.
1266      * <p>
1267      * Usually an application that uses a logging framework will log messages
1268      * through a logger facade defined (or supported) by that framework.
1269      * Applications that wish to use an external framework should log
1270      * through the facade associated with that framework.
1271      * <p>
1272      * A system class that needs to log messages will typically obtain
1273      * a {@link System.Logger} instance to route messages to the logging
1274      * framework selected by the application.
1275      * <p>
1276      * Libraries and classes that only need loggers to produce log messages
1277      * should not attempt to configure loggers by themselves, as that
1278      * would make them dependent from a specific implementation of the
1279      * {@code LoggerFinder} service.
1280      * <p>
1281      * <b>Message Levels and Mapping to backend levels</b>
1282      * <p>
1283      * A logger finder is responsible for mapping from a {@code
1284      * System.Logger.Level} to a level supported by the logging backend it uses.
1285      * <br>The default LoggerFinder using {@code java.util.logging} as the backend
1286      * maps {@code System.Logger} levels to
1287      * {@linkplain java.logging/java.util.logging.Level java.util.logging} levels
1288      * of corresponding severity - as described in {@link Logger.Level
1289      * Logger.Level}.
1290      *
1291      * @see java.lang.System
1292      * @see java.lang.System.Logger
1293      *
1294      * @since 9
1295      */
1296     @SuppressWarnings("doclint:reference") // cross-module links
1297     public abstract static class LoggerFinder {
1298 
1299         /**
1300          * Creates a new instance of {@code LoggerFinder}.
1301          *
1302          * @implNote It is recommended that a {@code LoggerFinder} service
1303          *   implementation does not perform any heavy initialization in its
1304          *   constructor, in order to avoid possible risks of deadlock or class
1305          *   loading cycles during the instantiation of the service provider.
1306          */
1307         protected LoggerFinder() {
1308         }
1309 
1310         /**
1311          * Returns an instance of {@link Logger Logger}
1312          * for the given {@code module}.
1313          *
1314          * @param name the name of the logger.
1315          * @param module the module for which the logger is being requested.
1316          *
1317          * @return a {@link Logger logger} suitable for use within the given
1318          *         module.
1319          * @throws NullPointerException if {@code name} is {@code null} or
1320          *        {@code module} is {@code null}.
1321          */
1322         public abstract Logger getLogger(String name, Module module);
1323 
1324         /**
1325          * Returns a localizable instance of {@link Logger Logger}
1326          * for the given {@code module}.
1327          * The returned logger will use the provided resource bundle for
1328          * message localization.
1329          *
1330          * @implSpec By default, this method calls {@link
1331          * #getLogger(java.lang.String, java.lang.Module)
1332          * this.getLogger(name, module)} to obtain a logger, then wraps that
1333          * logger in a {@link Logger} instance where all methods that do not
1334          * take a {@link ResourceBundle} as parameter are redirected to one
1335          * which does - passing the given {@code bundle} for
1336          * localization. So for instance, a call to {@link
1337          * Logger#log(Logger.Level, String) Logger.log(Level.INFO, msg)}
1338          * will end up as a call to {@link
1339          * Logger#log(Logger.Level, ResourceBundle, String, Object...)
1340          * Logger.log(Level.INFO, bundle, msg, (Object[])null)} on the wrapped
1341          * logger instance.
1342          * Note however that by default, string messages returned by {@link
1343          * java.util.function.Supplier Supplier&lt;String&gt;} will not be
1344          * localized, as it is assumed that such strings are messages which are
1345          * already constructed, rather than keys in a resource bundle.
1346          * <p>
1347          * An implementation of {@code LoggerFinder} may override this method,
1348          * for example, when the underlying logging backend provides its own
1349          * mechanism for localizing log messages, then such a
1350          * {@code LoggerFinder} would be free to return a logger
1351          * that makes direct use of the mechanism provided by the backend.
1352          *
1353          * @param name    the name of the logger.
1354          * @param bundle  a resource bundle; can be {@code null}.
1355          * @param module  the module for which the logger is being requested.
1356          * @return an instance of {@link Logger Logger}  which will use the
1357          * provided resource bundle for message localization.
1358          *
1359          * @throws NullPointerException if {@code name} is {@code null} or
1360          *         {@code module} is {@code null}.
1361          */
1362         public Logger getLocalizedLogger(String name, ResourceBundle bundle,
1363                                          Module module) {
1364             return new LocalizedLoggerWrapper<>(getLogger(name, module), bundle);
1365         }
1366 
1367         /**
1368          * Returns the {@code LoggerFinder} instance. There is one
1369          * single system-wide {@code LoggerFinder} instance in
1370          * the Java Runtime.  See the class specification of how the
1371          * {@link LoggerFinder LoggerFinder} implementation is located and
1372          * loaded.
1373          *
1374          * @return the {@link LoggerFinder LoggerFinder} instance.
1375          */
1376         public static LoggerFinder getLoggerFinder() {
1377             return accessProvider();
1378         }
1379 
1380 
1381         private static volatile LoggerFinder service;
1382         static LoggerFinder accessProvider() {
1383             // We do not need to synchronize: LoggerFinderLoader will
1384             // always return the same instance, so if we don't have it,
1385             // just fetch it again.
1386             LoggerFinder finder = service;
1387             if (finder == null) {
1388                 finder = LoggerFinderLoader.getLoggerFinder();
1389                 if (finder instanceof TemporaryLoggerFinder) return finder;
1390                 service = finder;
1391             }
1392             return finder;
1393         }
1394 
1395     }
1396 
1397 
1398     /**
1399      * Returns an instance of {@link Logger Logger} for the caller's
1400      * use.
1401      *
1402      * @implSpec
1403      * Instances returned by this method route messages to loggers
1404      * obtained by calling {@link LoggerFinder#getLogger(java.lang.String,
1405      * java.lang.Module) LoggerFinder.getLogger(name, module)}, where
1406      * {@code module} is the caller's module.
1407      * In cases where {@code System.getLogger} is called from a context where
1408      * there is no caller frame on the stack (e.g when called directly
1409      * from a JNI attached thread), {@code IllegalCallerException} is thrown.
1410      * To obtain a logger in such a context, use an auxiliary class that will
1411      * implicitly be identified as the caller, or use the system {@link
1412      * LoggerFinder#getLoggerFinder() LoggerFinder} to obtain a logger instead.
1413      * Note that doing the latter may eagerly initialize the underlying
1414      * logging system.
1415      *
1416      * @apiNote
1417      * This method may defer calling the {@link
1418      * LoggerFinder#getLogger(java.lang.String, java.lang.Module)
1419      * LoggerFinder.getLogger} method to create an actual logger supplied by
1420      * the logging backend, for instance, to allow loggers to be obtained during
1421      * the system initialization time.
1422      *
1423      * @param name the name of the logger.
1424      * @return an instance of {@link Logger} that can be used by the calling
1425      *         class.
1426      * @throws NullPointerException if {@code name} is {@code null}.
1427      * @throws IllegalCallerException if there is no Java caller frame on the
1428      *         stack.
1429      *
1430      * @since 9
1431      */
1432     @CallerSensitive
1433     public static Logger getLogger(String name) {
1434         Objects.requireNonNull(name);
1435         final Class<?> caller = Reflection.getCallerClass();
1436         if (caller == null) {
1437             throw new IllegalCallerException("no caller frame");
1438         }
1439         return LazyLoggers.getLogger(name, caller.getModule());
1440     }
1441 
1442     /**
1443      * Returns a localizable instance of {@link Logger
1444      * Logger} for the caller's use.
1445      * The returned logger will use the provided resource bundle for message
1446      * localization.
1447      *
1448      * @implSpec
1449      * The returned logger will perform message localization as specified
1450      * by {@link LoggerFinder#getLocalizedLogger(java.lang.String,
1451      * java.util.ResourceBundle, java.lang.Module)
1452      * LoggerFinder.getLocalizedLogger(name, bundle, module)}, where
1453      * {@code module} is the caller's module.
1454      * In cases where {@code System.getLogger} is called from a context where
1455      * there is no caller frame on the stack (e.g when called directly
1456      * from a JNI attached thread), {@code IllegalCallerException} is thrown.
1457      * To obtain a logger in such a context, use an auxiliary class that
1458      * will implicitly be identified as the caller, or use the system {@link
1459      * LoggerFinder#getLoggerFinder() LoggerFinder} to obtain a logger instead.
1460      * Note that doing the latter may eagerly initialize the underlying
1461      * logging system.
1462      *
1463      * @apiNote
1464      * This method is intended to be used after the system is fully initialized.
1465      * This method may trigger the immediate loading and initialization
1466      * of the {@link LoggerFinder} service, which may cause issues if the
1467      * Java Runtime is not ready to initialize the concrete service
1468      * implementation yet.
1469      * System classes which may be loaded early in the boot sequence and
1470      * need to log localized messages should create a logger using
1471      * {@link #getLogger(java.lang.String)} and then use the log methods that
1472      * take a resource bundle as parameter.
1473      *
1474      * @param name    the name of the logger.
1475      * @param bundle  a resource bundle.
1476      * @return an instance of {@link Logger} which will use the provided
1477      * resource bundle for message localization.
1478      * @throws NullPointerException if {@code name} is {@code null} or
1479      *         {@code bundle} is {@code null}.
1480      * @throws IllegalCallerException if there is no Java caller frame on the
1481      *         stack.
1482      *
1483      * @since 9
1484      */
1485     @CallerSensitive
1486     public static Logger getLogger(String name, ResourceBundle bundle) {
1487         final ResourceBundle rb = Objects.requireNonNull(bundle);
1488         Objects.requireNonNull(name);
1489         final Class<?> caller = Reflection.getCallerClass();
1490         if (caller == null) {
1491             throw new IllegalCallerException("no caller frame");
1492         }
1493         return LoggerFinder.accessProvider()
1494                 .getLocalizedLogger(name, rb, caller.getModule());
1495     }
1496 
1497     /**
1498      * Initiates the {@linkplain Runtime##shutdown shutdown sequence} of the Java Virtual
1499      * Machine. This method initiates the shutdown sequence (if it is not already initiated)
1500      * and then blocks indefinitely. This method neither returns nor throws an exception;
1501      * that is, it does not complete either normally or abruptly.
1502      * <p>
1503      * The argument serves as a status code. By convention, a nonzero status code
1504      * indicates abnormal termination.
1505      * <p>
1506      * The call {@code System.exit(n)} is effectively equivalent to the call:
1507      * {@snippet :
1508      *     Runtime.getRuntime().exit(n)
1509      * }
1510      *
1511      * @implNote
1512      * The initiation of the shutdown sequence is logged by {@link Runtime#exit(int)}.
1513      *
1514      * @param  status exit status.
1515      * @see    java.lang.Runtime#exit(int)
1516      */
1517     public static void exit(int status) {
1518         Runtime.getRuntime().exit(status);
1519     }
1520 
1521     /**
1522      * Returns whether the AOT system is recording training data.
1523      *
1524      * @return  whether the AOT system is recording training data.
1525      */
1526     public static native boolean AOTIsTraining();
1527 
1528     /**
1529      * Will stop the recording of AOT training data.
1530      */
1531     public static native void AOTEndTraining();
1532 
1533     /**
1534      * Runs the garbage collector in the Java Virtual Machine.
1535      * <p>
1536      * Calling the {@code gc} method suggests that the Java Virtual Machine
1537      * expend effort toward recycling unused objects in order to
1538      * make the memory they currently occupy available for reuse
1539      * by the Java Virtual Machine.
1540      * When control returns from the method call, the Java Virtual Machine
1541      * has made a best effort to reclaim space from all unused objects.
1542      * There is no guarantee that this effort will recycle any particular
1543      * number of unused objects, reclaim any particular amount of space, or
1544      * complete at any particular time, if at all, before the method returns or ever.
1545      * There is also no guarantee that this effort will determine
1546      * the change of reachability in any particular number of objects,
1547      * or that any particular number of {@link java.lang.ref.Reference Reference}
1548      * objects will be cleared and enqueued.
1549      *
1550      * <p>
1551      * The call {@code System.gc()} is effectively equivalent to the
1552      * call:
1553      * <blockquote><pre>
1554      * Runtime.getRuntime().gc()
1555      * </pre></blockquote>
1556      *
1557      * @see     java.lang.Runtime#gc()
1558      */
1559     public static void gc() {
1560         Runtime.getRuntime().gc();
1561     }
1562 
1563     /**
1564      * Runs the finalization methods of any objects pending finalization.
1565      *
1566      * Calling this method suggests that the Java Virtual Machine expend
1567      * effort toward running the {@code finalize} methods of objects
1568      * that have been found to be discarded but whose {@code finalize}
1569      * methods have not yet been run. When control returns from the
1570      * method call, the Java Virtual Machine has made a best effort to
1571      * complete all outstanding finalizations.
1572      * <p>
1573      * The call {@code System.runFinalization()} is effectively
1574      * equivalent to the call:
1575      * <blockquote><pre>
1576      * Runtime.getRuntime().runFinalization()
1577      * </pre></blockquote>
1578      *
1579      * @deprecated Finalization has been deprecated for removal.  See
1580      * {@link java.lang.Object#finalize} for background information and details
1581      * about migration options.
1582      * <p>
1583      * When running in a JVM in which finalization has been disabled or removed,
1584      * no objects will be pending finalization, so this method does nothing.
1585      *
1586      * @see     java.lang.Runtime#runFinalization()
1587      * @jls 12.6 Finalization of Class Instances
1588      */
1589     @Deprecated(since="18", forRemoval=true)
1590     @SuppressWarnings("removal")
1591     public static void runFinalization() {
1592         Runtime.getRuntime().runFinalization();
1593     }
1594 
1595     /**
1596      * Loads the native library specified by the filename argument.  The filename
1597      * argument must be an absolute path name.
1598      *
1599      * If the filename argument, when stripped of any platform-specific library
1600      * prefix, path, and file extension, indicates a library whose name is,
1601      * for example, L, and a native library called L is statically linked
1602      * with the VM, then the JNI_OnLoad_L function exported by the library
1603      * is invoked rather than attempting to load a dynamic library.
1604      * A filename matching the argument does not have to exist in the
1605      * file system.
1606      * See the <a href="{@docRoot}/../specs/jni/index.html"> JNI Specification</a>
1607      * for more details.
1608      *
1609      * Otherwise, the filename argument is mapped to a native library image in
1610      * an implementation-dependent manner.
1611      *
1612      * <p>
1613      * The call {@code System.load(name)} is effectively equivalent
1614      * to the call:
1615      * <blockquote><pre>
1616      * Runtime.getRuntime().load(name)
1617      * </pre></blockquote>
1618      *
1619      * @param      filename   the file to load.
1620      * @throws     UnsatisfiedLinkError  if either the filename is not an
1621      *             absolute path name, the native library is not statically
1622      *             linked with the VM, or the library cannot be mapped to
1623      *             a native library image by the host system.
1624      * @throws     NullPointerException if {@code filename} is {@code null}
1625      * @throws     IllegalCallerException if the caller is in a module that
1626      *             does not have native access enabled.
1627      *
1628      * @spec jni/index.html Java Native Interface Specification
1629      * @see        java.lang.Runtime#load(java.lang.String)
1630      */
1631     @CallerSensitive
1632     @Restricted
1633     public static void load(String filename) {
1634         Class<?> caller = Reflection.getCallerClass();
1635         Reflection.ensureNativeAccess(caller, System.class, "load", false);
1636         Runtime.getRuntime().load0(caller, filename);
1637     }
1638 
1639     /**
1640      * Loads the native library specified by the {@code libname}
1641      * argument.  The {@code libname} argument must not contain any platform
1642      * specific prefix, file extension or path. If a native library
1643      * called {@code libname} is statically linked with the VM, then the
1644      * JNI_OnLoad_{@code libname} function exported by the library is invoked.
1645      * See the <a href="{@docRoot}/../specs/jni/index.html"> JNI Specification</a>
1646      * for more details.
1647      *
1648      * Otherwise, the libname argument is loaded from a system library
1649      * location and mapped to a native library image in an
1650      * implementation-dependent manner.
1651      * <p>
1652      * The call {@code System.loadLibrary(name)} is effectively
1653      * equivalent to the call
1654      * <blockquote><pre>
1655      * Runtime.getRuntime().loadLibrary(name)
1656      * </pre></blockquote>
1657      *
1658      * @param      libname   the name of the library.
1659      * @throws     UnsatisfiedLinkError if either the libname argument
1660      *             contains a file path, the native library is not statically
1661      *             linked with the VM,  or the library cannot be mapped to a
1662      *             native library image by the host system.
1663      * @throws     NullPointerException if {@code libname} is {@code null}
1664      * @throws     IllegalCallerException if the caller is in a module that
1665      *             does not have native access enabled.
1666      *
1667      * @spec jni/index.html Java Native Interface Specification
1668      * @see        java.lang.Runtime#loadLibrary(java.lang.String)
1669      */
1670     @CallerSensitive
1671     @Restricted
1672     public static void loadLibrary(String libname) {
1673         Class<?> caller = Reflection.getCallerClass();
1674         Reflection.ensureNativeAccess(caller, System.class, "loadLibrary", false);
1675         Runtime.getRuntime().loadLibrary0(caller, libname);
1676     }
1677 
1678     /**
1679      * Maps a library name into a platform-specific string representing
1680      * a native library.
1681      *
1682      * @param      libname the name of the library.
1683      * @return     a platform-dependent native library name.
1684      * @throws     NullPointerException if {@code libname} is {@code null}
1685      * @see        java.lang.System#loadLibrary(java.lang.String)
1686      * @see        java.lang.ClassLoader#findLibrary(java.lang.String)
1687      * @since      1.2
1688      */
1689     public static native String mapLibraryName(String libname);
1690 
1691     /**
1692      * Create PrintStream for stdout/err based on encoding.
1693      */
1694     private static PrintStream newPrintStream(OutputStream out, String enc) {
1695         if (enc != null) {
1696             return new PrintStream(new BufferedOutputStream(out, 128), true,
1697                                    Charset.forName(enc, UTF_8.INSTANCE));
1698         }
1699         return new PrintStream(new BufferedOutputStream(out, 128), true);
1700     }
1701 
1702     /**
1703      * Logs an exception/error at initialization time to stdout or stderr.
1704      *
1705      * @param printToStderr to print to stderr rather than stdout
1706      * @param printStackTrace to print the stack trace
1707      * @param msg the message to print before the exception, can be {@code null}
1708      * @param e the exception or error
1709      */
1710     private static void logInitException(boolean printToStderr,
1711                                          boolean printStackTrace,
1712                                          String msg,
1713                                          Throwable e) {
1714         if (VM.initLevel() < 1) {
1715             throw new InternalError("system classes not initialized");
1716         }
1717         PrintStream log = (printToStderr) ? err : out;
1718         if (msg != null) {
1719             log.println(msg);
1720         }
1721         if (printStackTrace) {
1722             e.printStackTrace(log);
1723         } else {
1724             log.println(e);
1725             for (Throwable suppressed : e.getSuppressed()) {
1726                 log.println("Suppressed: " + suppressed);
1727             }
1728             Throwable cause = e.getCause();
1729             if (cause != null) {
1730                 log.println("Caused by: " + cause);
1731             }
1732         }
1733     }
1734 
1735     /**
1736      * Create the Properties object from a map - masking out system properties
1737      * that are not intended for public access.
1738      */
1739     private static Properties createProperties(Map<String, String> initialProps) {
1740         Properties properties = new Properties(initialProps.size());
1741         for (var entry : initialProps.entrySet()) {
1742             String prop = entry.getKey();
1743             switch (prop) {
1744                 // Do not add private system properties to the Properties
1745                 case "sun.nio.MaxDirectMemorySize":
1746                 case "sun.nio.PageAlignDirectMemory":
1747                     // used by java.lang.Integer.IntegerCache
1748                 case "java.lang.Integer.IntegerCache.high":
1749                     // used by sun.launcher.LauncherHelper
1750                 case "sun.java.launcher.diag":
1751                     // used by jdk.internal.loader.ClassLoaders
1752                 case "jdk.boot.class.path.append":
1753                     break;
1754                 default:
1755                     properties.put(prop, entry.getValue());
1756             }
1757         }
1758         return properties;
1759     }
1760 
1761     /**
1762      * Initialize the system class.  Called after thread initialization.
1763      */
1764     private static void initPhase1() {
1765 
1766         // register the shared secrets - do this first, since SystemProps.initProperties
1767         // might initialize CharsetDecoders that rely on it
1768         setJavaLangAccess();
1769 
1770         // VM might invoke JNU_NewStringPlatform() to set those encoding
1771         // sensitive properties (user.home, user.name, boot.class.path, etc.)
1772         // during "props" initialization.
1773         // The charset is initialized in System.c and does not depend on the Properties.
1774         Map<String, String> tempProps = SystemProps.initProperties();
1775         VersionProps.init(tempProps);
1776 
1777         // There are certain system configurations that may be controlled by
1778         // VM options such as the maximum amount of direct memory and
1779         // Integer cache size used to support the object identity semantics
1780         // of autoboxing.  Typically, the library will obtain these values
1781         // from the properties set by the VM.  If the properties are for
1782         // internal implementation use only, these properties should be
1783         // masked from the system properties.
1784         //
1785         // Save a private copy of the system properties object that
1786         // can only be accessed by the internal implementation.
1787         VM.saveProperties(tempProps);
1788         props = createProperties(tempProps);
1789 
1790         // Check if sun.jnu.encoding is supported. If not, replace it with UTF-8.
1791         var jnuEncoding = props.getProperty("sun.jnu.encoding");
1792         if (jnuEncoding == null || !Charset.isSupported(jnuEncoding)) {
1793             notSupportedJnuEncoding = jnuEncoding == null ? "null" : jnuEncoding;
1794             props.setProperty("sun.jnu.encoding", "UTF-8");
1795         }
1796 
1797         StaticProperty.javaHome();          // Load StaticProperty to cache the property values
1798 
1799         lineSeparator = props.getProperty("line.separator");
1800 
1801         FileInputStream fdIn = new In(FileDescriptor.in);
1802         FileOutputStream fdOut = new Out(FileDescriptor.out);
1803         FileOutputStream fdErr = new Out(FileDescriptor.err);
1804         initialIn = new BufferedInputStream(fdIn);
1805         setIn0(initialIn);
1806         // stdout/err.encoding are set when the VM is associated with the terminal,
1807         // thus they are equivalent to Console.charset(), otherwise the encodings
1808         // of those properties default to native.encoding
1809         setOut0(newPrintStream(fdOut, props.getProperty("stdout.encoding")));
1810         initialErr = newPrintStream(fdErr, props.getProperty("stderr.encoding"));
1811         setErr0(initialErr);
1812 
1813         // Setup Java signal handlers for HUP, TERM, and INT (where available).
1814         Terminator.setup();
1815 
1816         // Initialize any miscellaneous operating system settings that need to be
1817         // set for the class libraries. Currently this is no-op everywhere except
1818         // for Windows where the process-wide error mode is set before the java.io
1819         // classes are used.
1820         VM.initializeOSEnvironment();
1821 
1822         // start Finalizer and Reference Handler threads
1823         SharedSecrets.getJavaLangRefAccess().startThreads();
1824 
1825         // system properties, java.lang and other core classes are now initialized
1826         VM.initLevel(1);
1827     }
1828 
1829     /**
1830      * System.in.
1831      */
1832     private static class In extends FileInputStream {
1833         In(FileDescriptor fd) {
1834             super(fd);
1835         }
1836 
1837         @Override
1838         public int read() throws IOException {
1839             boolean attempted = Blocker.begin();
1840             try {
1841                 return super.read();
1842             } finally {
1843                 Blocker.end(attempted);
1844             }
1845         }
1846 
1847         @Override
1848         public int read(byte[] b) throws IOException {
1849             boolean attempted = Blocker.begin();
1850             try {
1851                 return super.read(b);
1852             } finally {
1853                 Blocker.end(attempted);
1854             }
1855         }
1856 
1857         @Override
1858         public int read(byte[] b, int off, int len) throws IOException {
1859             boolean attempted = Blocker.begin();
1860             try {
1861                 return super.read(b, off, len);
1862             } finally {
1863                 Blocker.end(attempted);
1864             }
1865         }
1866     }
1867 
1868     /**
1869      * System.out/System.err wrap this output stream.
1870      */
1871     private static class Out extends FileOutputStream {
1872         Out(FileDescriptor fd) {
1873             super(fd);
1874         }
1875 
1876         @Override
1877         public void write(int b) throws IOException {
1878             boolean attempted = Blocker.begin();
1879             try {
1880                 super.write(b);
1881             } finally {
1882                 Blocker.end(attempted);
1883             }
1884         }
1885 
1886         @Override
1887         public void write(byte[] b) throws IOException {
1888             boolean attempted = Blocker.begin();
1889             try {
1890                 super.write(b);
1891             } finally {
1892                 Blocker.end(attempted);
1893             }
1894         }
1895 
1896         @Override
1897         public void write(byte[] b, int off, int len) throws IOException {
1898             boolean attempted = Blocker.begin();
1899             try {
1900                 super.write(b, off, len);
1901             } finally {
1902                 Blocker.end(attempted);
1903             }
1904         }
1905     }
1906 
1907     // @see #initPhase2()
1908     static ModuleLayer bootLayer;
1909 
1910     /*
1911      * Invoked by VM.  Phase 2 module system initialization.
1912      * Only classes in java.base can be loaded in this phase.
1913      *
1914      * @param printToStderr print exceptions to stderr rather than stdout
1915      * @param printStackTrace print stack trace when exception occurs
1916      *
1917      * @return JNI_OK for success, JNI_ERR for failure
1918      */
1919     private static int initPhase2(boolean printToStderr, boolean printStackTrace) {
1920 
1921         try {
1922             bootLayer = ModuleBootstrap.boot();
1923         } catch (Exception | Error e) {
1924             logInitException(printToStderr, printStackTrace,
1925                              "Error occurred during initialization of boot layer", e);
1926             return -1; // JNI_ERR
1927         }
1928 
1929         // module system initialized
1930         VM.initLevel(2);
1931 
1932         return 0; // JNI_OK
1933     }
1934 
1935     /*
1936      * Invoked by VM.  Phase 3 is the final system initialization:
1937      * 1. set system class loader
1938      * 2. set TCCL
1939      *
1940      * This method must be called after the module system initialization.
1941      */
1942     private static void initPhase3() {
1943 
1944         // Emit a warning if java.io.tmpdir is set via the command line
1945         // to a directory that doesn't exist
1946         if (SystemProps.isBadIoTmpdir()) {
1947             System.err.println("WARNING: java.io.tmpdir directory does not exist");
1948         }
1949 
1950         String smProp = System.getProperty("java.security.manager");
1951         if (smProp != null) {
1952             switch (smProp) {
1953                 case "disallow":
1954                     break;
1955                 case "allow":
1956                 case "":
1957                 case "default":
1958                 default:
1959                     throw new Error("A command line option has attempted to allow or enable the Security Manager."
1960                             + " Enabling a Security Manager is not supported.");
1961             }
1962         }
1963 
1964         // Emit a warning if `sun.jnu.encoding` is not supported.
1965         if (notSupportedJnuEncoding != null) {
1966             System.err.println(
1967                     "WARNING: The encoding of the underlying platform's" +
1968                     " file system is not supported: " +
1969                     notSupportedJnuEncoding);
1970         }
1971 
1972         // initializing the system class loader
1973         VM.initLevel(3);
1974 
1975         // system class loader initialized
1976         ClassLoader scl = ClassLoader.initSystemClassLoader();
1977 
1978         // set TCCL
1979         Thread.currentThread().setContextClassLoader(scl);
1980 
1981         // system is fully initialized
1982         VM.initLevel(4);
1983     }
1984 
1985     private static void setJavaLangAccess() {
1986         // Allow privileged classes outside of java.lang
1987         SharedSecrets.setJavaLangAccess(new JavaLangAccess() {
1988             public List<Method> getDeclaredPublicMethods(Class<?> klass, String name, Class<?>... parameterTypes) {
1989                 return klass.getDeclaredPublicMethods(name, parameterTypes);
1990             }
1991             public Method findMethod(Class<?> klass, boolean publicOnly, String name, Class<?>... parameterTypes) {
1992                 return klass.findMethod(publicOnly, name, parameterTypes);
1993             }
1994             public jdk.internal.reflect.ConstantPool getConstantPool(Class<?> klass) {
1995                 return klass.getConstantPool();
1996             }
1997             public boolean casAnnotationType(Class<?> klass, AnnotationType oldType, AnnotationType newType) {
1998                 return klass.casAnnotationType(oldType, newType);
1999             }
2000             public AnnotationType getAnnotationType(Class<?> klass) {
2001                 return klass.getAnnotationType();
2002             }
2003             public Map<Class<? extends Annotation>, Annotation> getDeclaredAnnotationMap(Class<?> klass) {
2004                 return klass.getDeclaredAnnotationMap();
2005             }
2006             public byte[] getRawClassAnnotations(Class<?> klass) {
2007                 return klass.getRawAnnotations();
2008             }
2009             public byte[] getRawClassTypeAnnotations(Class<?> klass) {
2010                 return klass.getRawTypeAnnotations();
2011             }
2012             public byte[] getRawExecutableTypeAnnotations(Executable executable) {
2013                 return Class.getExecutableTypeAnnotationBytes(executable);
2014             }
2015             public <E extends Enum<E>>
2016             E[] getEnumConstantsShared(Class<E> klass) {
2017                 return klass.getEnumConstantsShared();
2018             }
2019             public void blockedOn(Interruptible b) {
2020                 Thread.currentThread().blockedOn(b);
2021             }
2022             public void registerShutdownHook(int slot, boolean registerShutdownInProgress, Runnable hook) {
2023                 Shutdown.add(slot, registerShutdownInProgress, hook);
2024             }
2025             @SuppressWarnings("removal")
2026             public void invokeFinalize(Object o) throws Throwable {
2027                 o.finalize();
2028             }
2029             public ConcurrentHashMap<?, ?> createOrGetClassLoaderValueMap(ClassLoader cl) {
2030                 return cl.createOrGetClassLoaderValueMap();
2031             }
2032             public Class<?> defineClass(ClassLoader loader, String name, byte[] b, ProtectionDomain pd, String source) {
2033                 return ClassLoader.defineClass1(loader, name, b, 0, b.length, pd, source);
2034             }
2035             public Class<?> defineClass(ClassLoader loader, Class<?> lookup, String name, byte[] b, ProtectionDomain pd,
2036                                         boolean initialize, int flags, Object classData) {
2037                 return ClassLoader.defineClass0(loader, lookup, name, b, 0, b.length, pd, initialize, flags, classData);
2038             }
2039             public Class<?> findBootstrapClassOrNull(String name) {
2040                 return ClassLoader.findBootstrapClassOrNull(name);
2041             }
2042             public Package definePackage(ClassLoader cl, String name, Module module) {
2043                 return cl.definePackage(name, module);
2044             }
2045             public Module defineModule(ClassLoader loader,
2046                                        ModuleDescriptor descriptor,
2047                                        URI uri) {
2048                 return new Module(null, loader, descriptor, uri);
2049             }
2050             public Module defineUnnamedModule(ClassLoader loader) {
2051                 return new Module(loader);
2052             }
2053             public void addReads(Module m1, Module m2) {
2054                 m1.implAddReads(m2);
2055             }
2056             public void addReadsAllUnnamed(Module m) {
2057                 m.implAddReadsAllUnnamed();
2058             }
2059             public void addExports(Module m, String pn) {
2060                 m.implAddExports(pn);
2061             }
2062             public void addExports(Module m, String pn, Module other) {
2063                 m.implAddExports(pn, other);
2064             }
2065             public void addExportsToAllUnnamed(Module m, String pn) {
2066                 m.implAddExportsToAllUnnamed(pn);
2067             }
2068             public void addOpens(Module m, String pn, Module other) {
2069                 m.implAddOpens(pn, other);
2070             }
2071             public void addOpensToAllUnnamed(Module m, String pn) {
2072                 m.implAddOpensToAllUnnamed(pn);
2073             }
2074             public void addOpensToAllUnnamed(Module m, Set<String> concealedPackages, Set<String> exportedPackages) {
2075                 m.implAddOpensToAllUnnamed(concealedPackages, exportedPackages);
2076             }
2077             public void addUses(Module m, Class<?> service) {
2078                 m.implAddUses(service);
2079             }
2080             public boolean isReflectivelyExported(Module m, String pn, Module other) {
2081                 return m.isReflectivelyExported(pn, other);
2082             }
2083             public boolean isReflectivelyOpened(Module m, String pn, Module other) {
2084                 return m.isReflectivelyOpened(pn, other);
2085             }
2086             public Module addEnableNativeAccess(Module m) {
2087                 return m.implAddEnableNativeAccess();
2088             }
2089             public boolean addEnableNativeAccess(ModuleLayer layer, String name) {
2090                 return layer.addEnableNativeAccess(name);
2091             }
2092             public void addEnableNativeAccessToAllUnnamed() {
2093                 Module.implAddEnableNativeAccessToAllUnnamed();
2094             }
2095             public void ensureNativeAccess(Module m, Class<?> owner, String methodName, Class<?> currentClass, boolean jni) {
2096                 m.ensureNativeAccess(owner, methodName, currentClass, jni);
2097             }
2098             public ServicesCatalog getServicesCatalog(ModuleLayer layer) {
2099                 return layer.getServicesCatalog();
2100             }
2101             public void bindToLoader(ModuleLayer layer, ClassLoader loader) {
2102                 layer.bindToLoader(loader);
2103             }
2104             public Stream<ModuleLayer> layers(ModuleLayer layer) {
2105                 return layer.layers();
2106             }
2107             public Stream<ModuleLayer> layers(ClassLoader loader) {
2108                 return ModuleLayer.layers(loader);
2109             }
2110 
2111             public int countPositives(byte[] bytes, int offset, int length) {
2112                 return StringCoding.countPositives(bytes, offset, length);
2113             }
2114             public int countNonZeroAscii(String s) {
2115                 return StringCoding.countNonZeroAscii(s);
2116             }
2117             public String newStringNoRepl(byte[] bytes, Charset cs) throws CharacterCodingException  {
2118                 return String.newStringNoRepl(bytes, cs);
2119             }
2120             public char getUTF16Char(byte[] bytes, int index) {
2121                 return StringUTF16.getChar(bytes, index);
2122             }
2123             public void putCharUTF16(byte[] bytes, int index, int ch) {
2124                 StringUTF16.putChar(bytes, index, ch);
2125             }
2126             public byte[] getBytesNoRepl(String s, Charset cs) throws CharacterCodingException {
2127                 return String.getBytesNoRepl(s, cs);
2128             }
2129 
2130             public String newStringUTF8NoRepl(byte[] bytes, int off, int len) {
2131                 return String.newStringUTF8NoRepl(bytes, off, len, true);
2132             }
2133 
2134             public byte[] getBytesUTF8NoRepl(String s) {
2135                 return String.getBytesUTF8NoRepl(s);
2136             }
2137 
2138             public void inflateBytesToChars(byte[] src, int srcOff, char[] dst, int dstOff, int len) {
2139                 StringLatin1.inflate(src, srcOff, dst, dstOff, len);
2140             }
2141 
2142             public int decodeASCII(byte[] src, int srcOff, char[] dst, int dstOff, int len) {
2143                 return String.decodeASCII(src, srcOff, dst, dstOff, len);
2144             }
2145 
2146             public int encodeASCII(char[] src, int srcOff, byte[] dst, int dstOff, int len) {
2147                 return StringCoding.implEncodeAsciiArray(src, srcOff, dst, dstOff, len);
2148             }
2149 
2150             public InputStream initialSystemIn() {
2151                 return initialIn;
2152             }
2153 
2154             public PrintStream initialSystemErr() {
2155                 return initialErr;
2156             }
2157 
2158             public void setCause(Throwable t, Throwable cause) {
2159                 t.setCause(cause);
2160             }
2161 
2162             public ProtectionDomain protectionDomain(Class<?> c) {
2163                 return c.protectionDomain();
2164             }
2165 
2166             public MethodHandle stringConcatHelper(String name, MethodType methodType) {
2167                 return StringConcatHelper.lookupStatic(name, methodType);
2168             }
2169 
2170             public long stringConcatInitialCoder() {
2171                 return StringConcatHelper.initialCoder();
2172             }
2173 
2174             public long stringConcatMix(long lengthCoder, String constant) {
2175                 return StringConcatHelper.mix(lengthCoder, constant);
2176             }
2177 
2178             public long stringConcatMix(long lengthCoder, char value) {
2179                 return StringConcatHelper.mix(lengthCoder, value);
2180             }
2181 
2182             public Object stringConcat1(String[] constants) {
2183                 return new StringConcatHelper.Concat1(constants);
2184             }
2185 
2186             public byte stringInitCoder() {
2187                 return String.COMPACT_STRINGS ? String.LATIN1 : String.UTF16;
2188             }
2189 
2190             public byte stringCoder(String str) {
2191                 return str.coder();
2192             }
2193 
2194             public int getCharsLatin1(long i, int index, byte[] buf) {
2195                 return StringLatin1.getChars(i, index, buf);
2196             }
2197 
2198             public int getCharsUTF16(long i, int index, byte[] buf) {
2199                 return StringUTF16.getChars(i, index, buf);
2200             }
2201 
2202             public String join(String prefix, String suffix, String delimiter, String[] elements, int size) {
2203                 return String.join(prefix, suffix, delimiter, elements, size);
2204             }
2205 
2206             public String concat(String prefix, Object value, String suffix) {
2207                 return StringConcatHelper.concat(prefix, value, suffix);
2208             }
2209 
2210             public Object classData(Class<?> c) {
2211                 return c.getClassData();
2212             }
2213 
2214             @Override
2215             public NativeLibraries nativeLibrariesFor(ClassLoader loader) {
2216                 return ClassLoader.nativeLibrariesFor(loader);
2217             }
2218 
2219             @Override
2220             public void exit(int statusCode) {
2221                 Shutdown.exit(statusCode);
2222             }
2223 
2224             public Thread[] getAllThreads() {
2225                 return Thread.getAllThreads();
2226             }
2227 
2228             public ThreadContainer threadContainer(Thread thread) {
2229                 return thread.threadContainer();
2230             }
2231 
2232             public void start(Thread thread, ThreadContainer container) {
2233                 thread.start(container);
2234             }
2235 
2236             public StackableScope headStackableScope(Thread thread) {
2237                 return thread.headStackableScopes();
2238             }
2239 
2240             public void setHeadStackableScope(StackableScope scope) {
2241                 Thread.setHeadStackableScope(scope);
2242             }
2243 
2244             public Thread currentCarrierThread() {
2245                 return Thread.currentCarrierThread();
2246             }
2247 
2248             public <T> T getCarrierThreadLocal(CarrierThreadLocal<T> local) {
2249                 return ((ThreadLocal<T>)local).getCarrierThreadLocal();
2250             }
2251 
2252             public <T> void setCarrierThreadLocal(CarrierThreadLocal<T> local, T value) {
2253                 ((ThreadLocal<T>)local).setCarrierThreadLocal(value);
2254             }
2255 
2256             public void removeCarrierThreadLocal(CarrierThreadLocal<?> local) {
2257                 ((ThreadLocal<?>)local).removeCarrierThreadLocal();
2258             }
2259 
2260             public boolean isCarrierThreadLocalPresent(CarrierThreadLocal<?> local) {
2261                 return ((ThreadLocal<?>)local).isCarrierThreadLocalPresent();
2262             }
2263 
2264             public Object[] scopedValueCache() {
2265                 return Thread.scopedValueCache();
2266             }
2267 
2268             public void setScopedValueCache(Object[] cache) {
2269                 Thread.setScopedValueCache(cache);
2270             }
2271 
2272             public Object scopedValueBindings() {
2273                 return Thread.scopedValueBindings();
2274             }
2275 
2276             public Continuation getContinuation(Thread thread) {
2277                 return thread.getContinuation();
2278             }
2279 
2280             public void setContinuation(Thread thread, Continuation continuation) {
2281                 thread.setContinuation(continuation);
2282             }
2283 
2284             public ContinuationScope virtualThreadContinuationScope() {
2285                 return VirtualThread.continuationScope();
2286             }
2287 
2288             public void parkVirtualThread() {
2289                 Thread thread = Thread.currentThread();
2290                 if (thread instanceof BaseVirtualThread vthread) {
2291                     vthread.park();
2292                 } else {
2293                     throw new WrongThreadException();
2294                 }
2295             }
2296 
2297             public void parkVirtualThread(long nanos) {
2298                 Thread thread = Thread.currentThread();
2299                 if (thread instanceof BaseVirtualThread vthread) {
2300                     vthread.parkNanos(nanos);
2301                 } else {
2302                     throw new WrongThreadException();
2303                 }
2304             }
2305 
2306             public void unparkVirtualThread(Thread thread) {
2307                 if (thread instanceof BaseVirtualThread vthread) {
2308                     vthread.unpark();
2309                 } else {
2310                     throw new WrongThreadException();
2311                 }
2312             }
2313 
2314             public Executor virtualThreadDefaultScheduler() {
2315                 return VirtualThread.defaultScheduler();
2316             }
2317 
2318             public Stream<ScheduledExecutorService> virtualThreadDelayedTaskSchedulers() {
2319                 return VirtualThread.delayedTaskSchedulers();
2320             }
2321 
2322             public StackWalker newStackWalkerInstance(Set<StackWalker.Option> options,
2323                                                       ContinuationScope contScope,
2324                                                       Continuation continuation) {
2325                 return StackWalker.newInstance(options, null, contScope, continuation);
2326             }
2327 
2328             public String getLoaderNameID(ClassLoader loader) {
2329                 return loader != null ? loader.nameAndId() : "null";
2330             }
2331 
2332             @Override
2333             public void copyToSegmentRaw(String string, MemorySegment segment, long offset) {
2334                 string.copyToSegmentRaw(segment, offset);
2335             }
2336 
2337             @Override
2338             public boolean bytesCompatible(String string, Charset charset) {
2339                 return string.bytesCompatible(charset);
2340             }
2341         });
2342     }
2343 }