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