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