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