1 /*
2 * Copyright (c) 1994, 2026, 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 * <div class="preview-block">
490 * <div class="preview-comment">
491 * The "identity hash code" of a {@linkplain Class#isValue() value object}
492 * is computed by combining the identity hash codes of the value object's fields recursively.
493 * </div>
494 * </div>
495 * @apiNote
496 * <div class="preview-block">
497 * <div class="preview-comment">
498 * Note that, like ==, this hash code exposes information about a value object's
499 * private fields that might otherwise be hidden by an identity object.
500 * Developers should be cautious about storing sensitive secrets in value object fields.
501 * </div>
502 * </div>
503 *
504 * @param x object for which the hashCode is to be calculated
505 * @return the hashCode
506 * @since 1.1
507 * @see Object#hashCode
508 * @see java.util.Objects#hashCode(Object)
509 */
510 @IntrinsicCandidate
511 public static native int identityHashCode(Object x);
512
513 /**
514 * System properties.
515 *
516 * See {@linkplain #getProperties getProperties} for details.
517 */
518 private static Properties props;
519
520 /**
521 * Determines the current system properties.
522 * <p>
523 * The current set of system properties for use by the
524 * {@link #getProperty(String)} method is returned as a
525 * {@code Properties} object. If there is no current set of
526 * system properties, a set of system properties is first created and
527 * initialized. This set of system properties includes a value
528 * for each of the following keys unless the description of the associated
529 * value indicates that the value is optional.
530 * <table class="striped" style="text-align:left">
531 * <caption style="display:none">Shows property keys and associated values</caption>
532 * <thead>
533 * <tr><th scope="col">Key</th>
534 * <th scope="col">Description of Associated Value</th></tr>
535 * </thead>
536 * <tbody>
537 * <tr><th scope="row">{@systemProperty java.version}</th>
538 * <td>Java Runtime Environment version, which may be interpreted
539 * as a {@link Runtime.Version}</td></tr>
540 * <tr><th scope="row">{@systemProperty java.version.date}</th>
541 * <td>Java Runtime Environment version date, in ISO-8601 YYYY-MM-DD
542 * format, which may be interpreted as a {@link
543 * java.time.LocalDate}</td></tr>
544 * <tr><th scope="row">{@systemProperty java.vendor}</th>
545 * <td>Java Runtime Environment vendor</td></tr>
546 * <tr><th scope="row">{@systemProperty java.vendor.url}</th>
547 * <td>Java vendor URL</td></tr>
548 * <tr><th scope="row">{@systemProperty java.vendor.version}</th>
549 * <td>Java vendor version <em>(optional)</em> </td></tr>
550 * <tr><th scope="row">{@systemProperty java.home}</th>
551 * <td>Java installation directory</td></tr>
552 * <tr><th scope="row">{@systemProperty java.vm.specification.version}</th>
553 * <td>Java Virtual Machine specification version, whose value is the
554 * {@linkplain Runtime.Version#feature feature} element of the
555 * {@linkplain Runtime#version() runtime version}</td></tr>
556 * <tr><th scope="row">{@systemProperty java.vm.specification.vendor}</th>
557 * <td>Java Virtual Machine specification vendor</td></tr>
558 * <tr><th scope="row">{@systemProperty java.vm.specification.name}</th>
559 * <td>Java Virtual Machine specification name</td></tr>
560 * <tr><th scope="row">{@systemProperty java.vm.version}</th>
561 * <td>Java Virtual Machine implementation version which may be
562 * interpreted as a {@link Runtime.Version}</td></tr>
563 * <tr><th scope="row">{@systemProperty java.vm.vendor}</th>
564 * <td>Java Virtual Machine implementation vendor</td></tr>
565 * <tr><th scope="row">{@systemProperty java.vm.name}</th>
566 * <td>Java Virtual Machine implementation name</td></tr>
567 * <tr><th scope="row">{@systemProperty java.specification.version}</th>
568 * <td>Java Runtime Environment specification version, whose value is
569 * the {@linkplain Runtime.Version#feature feature} element of the
570 * {@linkplain Runtime#version() runtime version}</td></tr>
571 * <tr><th scope="row">{@systemProperty java.specification.maintenance.version}</th>
572 * <td>Java Runtime Environment specification maintenance version,
573 * may be interpreted as a positive integer <em>(optional, see below)</em></td></tr>
574 * <tr><th scope="row">{@systemProperty java.specification.vendor}</th>
575 * <td>Java Runtime Environment specification vendor</td></tr>
576 * <tr><th scope="row">{@systemProperty java.specification.name}</th>
577 * <td>Java Runtime Environment specification name</td></tr>
578 * <tr><th scope="row">{@systemProperty java.class.version}</th>
579 * <td>{@linkplain java.lang.reflect.ClassFileFormatVersion#latest() Latest}
580 * Java class file format version recognized by the Java runtime as {@code "MAJOR.MINOR"}
581 * where {@link java.lang.reflect.ClassFileFormatVersion#major() MAJOR} and {@code MINOR}
582 * are both formatted as decimal integers</td></tr>
583 * <tr><th scope="row">{@systemProperty java.class.path}</th>
584 * <td>Java class path (refer to
585 * {@link ClassLoader#getSystemClassLoader()} for details)</td></tr>
586 * <tr><th scope="row">{@systemProperty java.library.path}</th>
587 * <td>List of paths to search when loading libraries</td></tr>
588 * <tr><th scope="row">{@systemProperty java.io.tmpdir}</th>
589 * <td>Default temp file path</td></tr>
590 * <tr><th scope="row">{@systemProperty os.name}</th>
591 * <td>Operating system name</td></tr>
592 * <tr><th scope="row">{@systemProperty os.arch}</th>
593 * <td>Operating system architecture</td></tr>
594 * <tr><th scope="row">{@systemProperty os.version}</th>
595 * <td>Operating system version</td></tr>
596 * <tr><th scope="row">{@systemProperty file.separator}</th>
597 * <td>File separator ("/" on UNIX)</td></tr>
598 * <tr><th scope="row">{@systemProperty path.separator}</th>
599 * <td>Path separator (":" on UNIX)</td></tr>
600 * <tr><th scope="row">{@systemProperty line.separator}</th>
601 * <td>Line separator ("\n" on UNIX)</td></tr>
602 * <tr><th scope="row">{@systemProperty user.name}</th>
603 * <td>User's account name</td></tr>
604 * <tr><th scope="row">{@systemProperty user.home}</th>
605 * <td>User's home directory</td></tr>
606 * <tr><th scope="row">{@systemProperty user.dir}</th>
607 * <td>User's current working directory</td></tr>
608 * <tr><th scope="row">{@systemProperty native.encoding}</th>
609 * <td>Character encoding name derived from the host environment and
610 * the user's settings. Setting this system property on the command line
611 * has no effect.</td></tr>
612 * <tr><th scope="row">{@systemProperty stdin.encoding}</th>
613 * <td>Character encoding name for {@link System#in System.in}.
614 * The Java runtime can be started with the system property set to {@code UTF-8}.
615 * Starting it with the property set to another value results in unspecified behavior.
616 * <tr><th scope="row">{@systemProperty stdout.encoding}</th>
617 * <td>Character encoding name for {@link System#out System.out} and
618 * {@link System#console() System.console()}.
619 * The Java runtime can be started with the system property set to {@code UTF-8}.
620 * Starting it with the property set to another value results in unspecified behavior.
621 * <tr><th scope="row">{@systemProperty stderr.encoding}</th>
622 * <td>Character encoding name for {@link System#err System.err}.
623 * The Java runtime can be started with the system property set to {@code UTF-8}.
624 * Starting it with the property set to another value results in unspecified behavior.
625 * </tbody>
626 * </table>
627 * <p>
628 * The {@code java.specification.maintenance.version} property is
629 * defined if the specification implemented by this runtime at the
630 * time of its construction had undergone a <a
631 * href="https://jcp.org/en/procedures/jcp2#3.6.4">maintenance
632 * release</a>. When defined, its value identifies that
633 * maintenance release. To indicate the first maintenance release
634 * this property will have the value {@code "1"}, to indicate the
635 * second maintenance release this property will have the value
636 * {@code "2"}, and so on.
637 * <p>
638 * Multiple paths in a system property value are separated by the path
639 * separator character of the platform.
640 * <p>
641 * Additional locale-related system properties defined by the
642 * {@link Locale##default_locale Default Locale} section in the {@code Locale}
643 * class description may also be obtained with this method.
644 *
645 * @apiNote
646 * <strong>Changing a standard system property may have unpredictable results
647 * unless otherwise specified.</strong>
648 * Property values may be cached during initialization or on first use.
649 * Setting a standard property after initialization using {@link #getProperties()},
650 * {@link #setProperties(Properties)}, {@link #setProperty(String, String)}, or
651 * {@link #clearProperty(String)} may not have the desired effect.
652 *
653 * @implNote
654 * In addition to the standard system properties, the system
655 * properties may include the following keys:
656 * <table class="striped">
657 * <caption style="display:none">Shows property keys and associated values</caption>
658 * <thead>
659 * <tr><th scope="col">Key</th>
660 * <th scope="col">Description of Associated Value</th></tr>
661 * </thead>
662 * <tbody>
663 * <tr><th scope="row">{@systemProperty jdk.module.path}</th>
664 * <td>The application module path</td></tr>
665 * <tr><th scope="row">{@systemProperty jdk.module.upgrade.path}</th>
666 * <td>The upgrade module path</td></tr>
667 * <tr><th scope="row">{@systemProperty jdk.module.main}</th>
668 * <td>The module name of the initial/main module</td></tr>
669 * <tr><th scope="row">{@systemProperty jdk.module.main.class}</th>
670 * <td>The main class name of the initial module</td></tr>
671 * <tr><th scope="row">{@systemProperty file.encoding}</th>
672 * <td>The name of the default charset, defaults to {@code UTF-8}.
673 * The property may be set on the command line to the value
674 * {@code UTF-8} or {@code COMPAT}. If set on the command line to
675 * the value {@code COMPAT} then the value is replaced with the
676 * value of the {@code native.encoding} property during startup.
677 * Setting the property to a value other than {@code UTF-8} or
678 * {@code COMPAT} results in unspecified behavior.
679 * </td></tr>
680 * </tbody>
681 * </table>
682 *
683 * @return the system properties
684 * @see #setProperties
685 * @see java.util.Properties
686 */
687 public static Properties getProperties() {
688 return props;
689 }
690
691 /**
692 * Returns the system-dependent line separator string. It always
693 * returns the same value - the initial value of the {@linkplain
694 * #getProperty(String) system property} {@code line.separator}.
695 *
696 * <p>On UNIX systems, it returns {@code "\n"}; on Microsoft
697 * Windows systems it returns {@code "\r\n"}.
698 *
699 * @return the system-dependent line separator string
700 * @since 1.7
701 */
702 public static String lineSeparator() {
703 return lineSeparator;
704 }
705
706 private static String lineSeparator;
707
708 /**
709 * Sets the system properties to the {@code Properties} argument.
710 * <p>
711 * The argument becomes the current set of system properties for use
712 * by the {@link #getProperty(String)} method. If the argument is
713 * {@code null}, then the current set of system properties is
714 * forgotten.
715 *
716 * @apiNote
717 * <strong>Changing a standard system property may have unpredictable results
718 * unless otherwise specified</strong>.
719 * See {@linkplain #getProperties getProperties} for details.
720 *
721 * @param props the new system properties.
722 * @see #getProperties
723 * @see java.util.Properties
724 */
725 public static void setProperties(Properties props) {
726 if (props == null) {
727 Map<String, String> tempProps = SystemProps.initProperties();
728 VersionProps.init(tempProps);
729 props = createProperties(tempProps);
730 }
731 System.props = props;
732 }
733
734 /**
735 * Gets the system property indicated by the specified key.
736 * <p>
737 * If there is no current set of system properties, a set of system
738 * properties is first created and initialized in the same manner as
739 * for the {@code getProperties} method.
740 *
741 * @apiNote
742 * <strong>Changing a standard system property may have unpredictable results
743 * unless otherwise specified</strong>.
744 * See {@linkplain #getProperties getProperties} for details.
745 *
746 * @param key the name of the system property.
747 * @return the string value of the system property,
748 * or {@code null} if there is no property with that key.
749 *
750 * @throws NullPointerException if {@code key} is {@code null}.
751 * @throws IllegalArgumentException if {@code key} is empty.
752 * @see #setProperty
753 * @see java.lang.System#getProperties()
754 */
755 public static String getProperty(String key) {
756 checkKey(key);
757 return props.getProperty(key);
758 }
759
760 /**
761 * Gets the system property indicated by the specified key.
762 * <p>
763 * If there is no current set of system properties, a set of system
764 * properties is first created and initialized in the same manner as
765 * for the {@code getProperties} method.
766 *
767 * @param key the name of the system property.
768 * @param def a default value.
769 * @return the string value of the system property,
770 * or the default value if there is no property with that key.
771 *
772 * @throws NullPointerException if {@code key} is {@code null}.
773 * @throws IllegalArgumentException if {@code key} is empty.
774 * @see #setProperty
775 * @see java.lang.System#getProperties()
776 */
777 public static String getProperty(String key, String def) {
778 checkKey(key);
779 return props.getProperty(key, def);
780 }
781
782 /**
783 * Sets the system property indicated by the specified key.
784 *
785 * @apiNote
786 * <strong>Changing a standard system property may have unpredictable results
787 * unless otherwise specified</strong>.
788 * See {@linkplain #getProperties getProperties} for details.
789 *
790 * @param key the name of the system property.
791 * @param value the value of the system property.
792 * @return the previous value of the system property,
793 * or {@code null} if it did not have one.
794 *
795 * @throws NullPointerException if {@code key} or
796 * {@code value} is {@code null}.
797 * @throws IllegalArgumentException if {@code key} is empty.
798 * @see #getProperty
799 * @see java.lang.System#getProperty(java.lang.String)
800 * @see java.lang.System#getProperty(java.lang.String, java.lang.String)
801 * @since 1.2
802 */
803 public static String setProperty(String key, String value) {
804 checkKey(key);
805 return (String) props.setProperty(key, value);
806 }
807
808 /**
809 * Removes the system property indicated by the specified key.
810 *
811 * @apiNote
812 * <strong>Changing a standard system property may have unpredictable results
813 * unless otherwise specified</strong>.
814 * See {@linkplain #getProperties getProperties} method for details.
815 *
816 * @param key the name of the system property to be removed.
817 * @return the previous string value of the system property,
818 * or {@code null} if there was no property with that key.
819 *
820 * @throws NullPointerException if {@code key} is {@code null}.
821 * @throws IllegalArgumentException if {@code key} is empty.
822 * @see #getProperty
823 * @see #setProperty
824 * @see java.util.Properties
825 * @since 1.5
826 */
827 public static String clearProperty(String key) {
828 checkKey(key);
829 return (String) props.remove(key);
830 }
831
832 private static void checkKey(String key) {
833 if (key == null) {
834 throw new NullPointerException("key can't be null");
835 }
836 if (key.isEmpty()) {
837 throw new IllegalArgumentException("key can't be empty");
838 }
839 }
840
841 /**
842 * Gets the value of the specified environment variable. An
843 * environment variable is a system-dependent external named
844 * value.
845 *
846 * <p><a id="EnvironmentVSSystemProperties"><i>System
847 * properties</i> and <i>environment variables</i></a> are both
848 * conceptually mappings between names and values. Both
849 * mechanisms can be used to pass user-defined information to a
850 * Java process. Environment variables have a more global effect,
851 * because they are visible to all descendants of the process
852 * which defines them, not just the immediate Java subprocess.
853 * They can have subtly different semantics, such as case
854 * insensitivity, on different operating systems. For these
855 * reasons, environment variables are more likely to have
856 * unintended side effects. It is best to use system properties
857 * where possible. Environment variables should be used when a
858 * global effect is desired, or when an external system interface
859 * requires an environment variable (such as {@code PATH}).
860 *
861 * <p>On UNIX systems the alphabetic case of {@code name} is
862 * typically significant, while on Microsoft Windows systems it is
863 * typically not. For example, the expression
864 * {@code System.getenv("FOO").equals(System.getenv("foo"))}
865 * is likely to be true on Microsoft Windows.
866 *
867 * @param name the name of the environment variable
868 * @return the string value of the variable, or {@code null}
869 * if the variable is not defined in the system environment
870 * @throws NullPointerException if {@code name} is {@code null}
871 * @see #getenv()
872 * @see ProcessBuilder#environment()
873 */
874 public static String getenv(String name) {
875 return ProcessEnvironment.getenv(name);
876 }
877
878
879 /**
880 * Returns an unmodifiable string map view of the current system environment.
881 * The environment is a system-dependent mapping from names to
882 * values which is passed from parent to child processes.
883 *
884 * <p>If the system does not support environment variables, an
885 * empty map is returned.
886 *
887 * <p>The returned map will never contain null keys or values.
888 * Attempting to query the presence of a null key or value will
889 * throw a {@link NullPointerException}. Attempting to query
890 * the presence of a key or value which is not of type
891 * {@link String} will throw a {@link ClassCastException}.
892 *
893 * <p>The returned map and its collection views may not obey the
894 * general contract of the {@link Object#equals} and
895 * {@link Object#hashCode} methods.
896 *
897 * <p>The returned map is typically case-sensitive on all platforms.
898 *
899 * <p>When passing information to a Java subprocess,
900 * <a href=#EnvironmentVSSystemProperties>system properties</a>
901 * are generally preferred over environment variables.
902 *
903 * @return the environment as a map of variable names to values
904 * @see #getenv(String)
905 * @see ProcessBuilder#environment()
906 * @since 1.5
907 */
908 public static java.util.Map<String,String> getenv() {
909 return ProcessEnvironment.getenv();
910 }
911
912 /**
913 * {@code System.Logger} instances log messages that will be
914 * routed to the underlying logging framework the {@link System.LoggerFinder
915 * LoggerFinder} uses.
916 *
917 * {@code System.Logger} instances are typically obtained from
918 * the {@link java.lang.System System} class, by calling
919 * {@link java.lang.System#getLogger(java.lang.String) System.getLogger(loggerName)}
920 * or {@link java.lang.System#getLogger(java.lang.String, java.util.ResourceBundle)
921 * System.getLogger(loggerName, bundle)}.
922 *
923 * @see java.lang.System#getLogger(java.lang.String)
924 * @see java.lang.System#getLogger(java.lang.String, java.util.ResourceBundle)
925 * @see java.lang.System.LoggerFinder
926 *
927 * @since 9
928 */
929 public interface Logger {
930
931 /**
932 * System {@linkplain Logger loggers} levels.
933 *
934 * A level has a {@linkplain #getName() name} and {@linkplain
935 * #getSeverity() severity}.
936 * Level values are {@link #ALL}, {@link #TRACE}, {@link #DEBUG},
937 * {@link #INFO}, {@link #WARNING}, {@link #ERROR}, {@link #OFF},
938 * by order of increasing severity.
939 * <br>
940 * {@link #ALL} and {@link #OFF}
941 * are simple markers with severities mapped respectively to
942 * {@link java.lang.Integer#MIN_VALUE Integer.MIN_VALUE} and
943 * {@link java.lang.Integer#MAX_VALUE Integer.MAX_VALUE}.
944 * <p>
945 * <b>Severity values and Mapping to {@code java.util.logging.Level}.</b>
946 * <p>
947 * {@linkplain System.Logger.Level System logger levels} are mapped to
948 * {@linkplain java.logging/java.util.logging.Level java.util.logging levels}
949 * of corresponding severity.
950 * <br>The mapping is as follows:
951 * <br><br>
952 * <table class="striped">
953 * <caption>System.Logger Severity Level Mapping</caption>
954 * <thead>
955 * <tr><th scope="col">System.Logger Levels</th>
956 * <th scope="col">java.util.logging Levels</th>
957 * </thead>
958 * <tbody>
959 * <tr><th scope="row">{@link Logger.Level#ALL ALL}</th>
960 * <td>{@link java.logging/java.util.logging.Level#ALL ALL}</td>
961 * <tr><th scope="row">{@link Logger.Level#TRACE TRACE}</th>
962 * <td>{@link java.logging/java.util.logging.Level#FINER FINER}</td>
963 * <tr><th scope="row">{@link Logger.Level#DEBUG DEBUG}</th>
964 * <td>{@link java.logging/java.util.logging.Level#FINE FINE}</td>
965 * <tr><th scope="row">{@link Logger.Level#INFO INFO}</th>
966 * <td>{@link java.logging/java.util.logging.Level#INFO INFO}</td>
967 * <tr><th scope="row">{@link Logger.Level#WARNING WARNING}</th>
968 * <td>{@link java.logging/java.util.logging.Level#WARNING WARNING}</td>
969 * <tr><th scope="row">{@link Logger.Level#ERROR ERROR}</th>
970 * <td>{@link java.logging/java.util.logging.Level#SEVERE SEVERE}</td>
971 * <tr><th scope="row">{@link Logger.Level#OFF OFF}</th>
972 * <td>{@link java.logging/java.util.logging.Level#OFF OFF}</td>
973 * </tbody>
974 * </table>
975 *
976 * @since 9
977 *
978 * @see java.lang.System.LoggerFinder
979 * @see java.lang.System.Logger
980 */
981 @SuppressWarnings("doclint:reference") // cross-module links
982 public enum Level {
983
984 // for convenience, we're reusing java.util.logging.Level int values
985 // the mapping logic in sun.util.logging.PlatformLogger depends
986 // on this.
987 /**
988 * A marker to indicate that all levels are enabled.
989 * This level {@linkplain #getSeverity() severity} is
990 * {@link Integer#MIN_VALUE}.
991 */
992 ALL(Integer.MIN_VALUE), // typically mapped to/from j.u.l.Level.ALL
993 /**
994 * {@code TRACE} level: usually used to log diagnostic information.
995 * This level {@linkplain #getSeverity() severity} is
996 * {@code 400}.
997 */
998 TRACE(400), // typically mapped to/from j.u.l.Level.FINER
999 /**
1000 * {@code DEBUG} level: usually used to log debug information traces.
1001 * This level {@linkplain #getSeverity() severity} is
1002 * {@code 500}.
1003 */
1004 DEBUG(500), // typically mapped to/from j.u.l.Level.FINEST/FINE/CONFIG
1005 /**
1006 * {@code INFO} level: usually used to log information messages.
1007 * This level {@linkplain #getSeverity() severity} is
1008 * {@code 800}.
1009 */
1010 INFO(800), // typically mapped to/from j.u.l.Level.INFO
1011 /**
1012 * {@code WARNING} level: usually used to log warning messages.
1013 * This level {@linkplain #getSeverity() severity} is
1014 * {@code 900}.
1015 */
1016 WARNING(900), // typically mapped to/from j.u.l.Level.WARNING
1017 /**
1018 * {@code ERROR} level: usually used to log error messages.
1019 * This level {@linkplain #getSeverity() severity} is
1020 * {@code 1000}.
1021 */
1022 ERROR(1000), // typically mapped to/from j.u.l.Level.SEVERE
1023 /**
1024 * A marker to indicate that all levels are disabled.
1025 * This level {@linkplain #getSeverity() severity} is
1026 * {@link Integer#MAX_VALUE}.
1027 */
1028 OFF(Integer.MAX_VALUE); // typically mapped to/from j.u.l.Level.OFF
1029
1030 private final int severity;
1031
1032 private Level(int severity) {
1033 this.severity = severity;
1034 }
1035
1036 /**
1037 * Returns the name of this level.
1038 * @return this level {@linkplain #name()}.
1039 */
1040 public final String getName() {
1041 return name();
1042 }
1043
1044 /**
1045 * Returns the severity of this level.
1046 * A higher severity means a more severe condition.
1047 * @return this level severity.
1048 */
1049 public final int getSeverity() {
1050 return severity;
1051 }
1052 }
1053
1054 /**
1055 * Returns the name of this logger.
1056 *
1057 * @return the logger name.
1058 */
1059 public String getName();
1060
1061 /**
1062 * Checks if a message of the given level would be logged by
1063 * this logger.
1064 *
1065 * @param level the log message level.
1066 * @return {@code true} if the given log message level is currently
1067 * being logged.
1068 *
1069 * @throws NullPointerException if {@code level} is {@code null}.
1070 */
1071 public boolean isLoggable(Level level);
1072
1073 /**
1074 * Logs a message.
1075 *
1076 * @implSpec The default implementation for this method calls
1077 * {@code this.log(level, (ResourceBundle)null, msg, (Object[])null);}
1078 *
1079 * @param level the log message level.
1080 * @param msg the string message (or a key in the message catalog, if
1081 * this logger is a {@link
1082 * LoggerFinder#getLocalizedLogger(java.lang.String,
1083 * java.util.ResourceBundle, java.lang.Module) localized logger});
1084 * can be {@code null}.
1085 *
1086 * @throws NullPointerException if {@code level} is {@code null}.
1087 */
1088 public default void log(Level level, String msg) {
1089 log(level, (ResourceBundle) null, msg, (Object[]) null);
1090 }
1091
1092 /**
1093 * Logs a lazily supplied message.
1094 *
1095 * If the logger is currently enabled for the given log message level
1096 * then a message is logged that is the result produced by the
1097 * given supplier function. Otherwise, the supplier is not operated on.
1098 *
1099 * @implSpec When logging is enabled for the given level, the default
1100 * implementation for this method calls
1101 * {@code this.log(level, (ResourceBundle)null, msgSupplier.get(), (Object[])null);}
1102 *
1103 * @param level the log message level.
1104 * @param msgSupplier a supplier function that produces a message.
1105 *
1106 * @throws NullPointerException if {@code level} is {@code null},
1107 * or {@code msgSupplier} is {@code null}.
1108 */
1109 public default void log(Level level, Supplier<String> msgSupplier) {
1110 Objects.requireNonNull(msgSupplier);
1111 if (isLoggable(Objects.requireNonNull(level))) {
1112 log(level, (ResourceBundle) null, msgSupplier.get(), (Object[]) null);
1113 }
1114 }
1115
1116 /**
1117 * Logs a message produced from the given object.
1118 *
1119 * If the logger is currently enabled for the given log message level then
1120 * a message is logged that, by default, is the result produced from
1121 * calling toString on the given object.
1122 * Otherwise, the object is not operated on.
1123 *
1124 * @implSpec When logging is enabled for the given level, the default
1125 * implementation for this method calls
1126 * {@code this.log(level, (ResourceBundle)null, obj.toString(), (Object[])null);}
1127 *
1128 * @param level the log message level.
1129 * @param obj the object to log.
1130 *
1131 * @throws NullPointerException if {@code level} is {@code null}, or
1132 * {@code obj} is {@code null}.
1133 */
1134 public default void log(Level level, Object obj) {
1135 Objects.requireNonNull(obj);
1136 if (isLoggable(Objects.requireNonNull(level))) {
1137 this.log(level, (ResourceBundle) null, obj.toString(), (Object[]) null);
1138 }
1139 }
1140
1141 /**
1142 * Logs a message associated with a given throwable.
1143 *
1144 * @implSpec The default implementation for this method calls
1145 * {@code this.log(level, (ResourceBundle)null, msg, thrown);}
1146 *
1147 * @param level the log message level.
1148 * @param msg the string message (or a key in the message catalog, if
1149 * this logger is a {@link
1150 * LoggerFinder#getLocalizedLogger(java.lang.String,
1151 * java.util.ResourceBundle, java.lang.Module) localized logger});
1152 * can be {@code null}.
1153 * @param thrown a {@code Throwable} associated with the log message;
1154 * can be {@code null}.
1155 *
1156 * @throws NullPointerException if {@code level} is {@code null}.
1157 */
1158 public default void log(Level level, String msg, Throwable thrown) {
1159 this.log(level, null, msg, thrown);
1160 }
1161
1162 /**
1163 * Logs a lazily supplied message associated with a given throwable.
1164 *
1165 * If the logger is currently enabled for the given log message level
1166 * then a message is logged that is the result produced by the
1167 * given supplier function. Otherwise, the supplier is not operated on.
1168 *
1169 * @implSpec When logging is enabled for the given level, the default
1170 * implementation for this method calls
1171 * {@code this.log(level, (ResourceBundle)null, msgSupplier.get(), thrown);}
1172 *
1173 * @param level one of the log message level identifiers.
1174 * @param msgSupplier a supplier function that produces a message.
1175 * @param thrown a {@code Throwable} associated with log message;
1176 * can be {@code null}.
1177 *
1178 * @throws NullPointerException if {@code level} is {@code null}, or
1179 * {@code msgSupplier} is {@code null}.
1180 */
1181 public default void log(Level level, Supplier<String> msgSupplier,
1182 Throwable thrown) {
1183 Objects.requireNonNull(msgSupplier);
1184 if (isLoggable(Objects.requireNonNull(level))) {
1185 this.log(level, null, msgSupplier.get(), thrown);
1186 }
1187 }
1188
1189 /**
1190 * Logs a message with an optional list of parameters.
1191 *
1192 * @implSpec The default implementation for this method calls
1193 * {@code this.log(level, (ResourceBundle)null, format, params);}
1194 *
1195 * @param level one of the log message level identifiers.
1196 * @param format the string message format in {@link
1197 * java.text.MessageFormat} format, (or a key in the message
1198 * catalog, if this logger is a {@link
1199 * LoggerFinder#getLocalizedLogger(java.lang.String,
1200 * java.util.ResourceBundle, java.lang.Module) localized logger});
1201 * can be {@code null}.
1202 * @param params an optional list of parameters to the message (may be
1203 * none).
1204 *
1205 * @throws NullPointerException if {@code level} is {@code null}.
1206 */
1207 public default void log(Level level, String format, Object... params) {
1208 this.log(level, null, format, params);
1209 }
1210
1211 /**
1212 * Logs a localized message associated with a given throwable.
1213 *
1214 * If the given resource bundle is non-{@code null}, the {@code msg}
1215 * string is localized using the given resource bundle.
1216 * Otherwise the {@code msg} string is not localized.
1217 *
1218 * @param level the log message level.
1219 * @param bundle a resource bundle to localize {@code msg}; can be
1220 * {@code null}.
1221 * @param msg the string message (or a key in the message catalog,
1222 * if {@code bundle} is not {@code null}); can be {@code null}.
1223 * @param thrown a {@code Throwable} associated with the log message;
1224 * can be {@code null}.
1225 *
1226 * @throws NullPointerException if {@code level} is {@code null}.
1227 */
1228 public void log(Level level, ResourceBundle bundle, String msg,
1229 Throwable thrown);
1230
1231 /**
1232 * Logs a message with resource bundle and an optional list of
1233 * parameters.
1234 *
1235 * If the given resource bundle is non-{@code null}, the {@code format}
1236 * string is localized using the given resource bundle.
1237 * Otherwise the {@code format} string is not localized.
1238 *
1239 * @param level the log message level.
1240 * @param bundle a resource bundle to localize {@code format}; can be
1241 * {@code null}.
1242 * @param format the string message format in {@link
1243 * java.text.MessageFormat} format, (or a key in the message
1244 * catalog if {@code bundle} is not {@code null}); can be {@code null}.
1245 * @param params an optional list of parameters to the message (may be
1246 * none).
1247 *
1248 * @throws NullPointerException if {@code level} is {@code null}.
1249 */
1250 public void log(Level level, ResourceBundle bundle, String format,
1251 Object... params);
1252 }
1253
1254 /**
1255 * The {@code LoggerFinder} service is responsible for creating, managing,
1256 * and configuring loggers to the underlying framework it uses.
1257 *
1258 * A logger finder is a concrete implementation of this class that has a
1259 * zero-argument constructor and implements the abstract methods defined
1260 * by this class.
1261 * The loggers returned from a logger finder are capable of routing log
1262 * messages to the logging backend this provider supports.
1263 * A given invocation of the Java Runtime maintains a single
1264 * system-wide LoggerFinder instance that is loaded as follows:
1265 * <ul>
1266 * <li>First it finds any custom {@code LoggerFinder} provider
1267 * using the {@link java.util.ServiceLoader} facility with the
1268 * {@linkplain ClassLoader#getSystemClassLoader() system class
1269 * loader}.</li>
1270 * <li>If no {@code LoggerFinder} provider is found, the system default
1271 * {@code LoggerFinder} implementation will be used.</li>
1272 * </ul>
1273 * <p>
1274 * An application can replace the logging backend
1275 * <i>even when the java.logging module is present</i>, by simply providing
1276 * and declaring an implementation of the {@link LoggerFinder} service.
1277 * <p>
1278 * <b>Default Implementation</b>
1279 * <p>
1280 * The system default {@code LoggerFinder} implementation uses
1281 * {@code java.util.logging} as the backend framework when the
1282 * {@code java.logging} module is present.
1283 * It returns a {@linkplain System.Logger logger} instance
1284 * that will route log messages to a {@link java.logging/java.util.logging.Logger
1285 * java.util.logging.Logger}. Otherwise, if {@code java.logging} is not
1286 * present, the default implementation will return a simple logger
1287 * instance that will route log messages of {@code INFO} level and above to
1288 * the console ({@code System.err}).
1289 * <p>
1290 * <b>Logging Configuration</b>
1291 * <p>
1292 * {@linkplain Logger Logger} instances obtained from the
1293 * {@code LoggerFinder} factory methods are not directly configurable by
1294 * the application. Configuration is the responsibility of the underlying
1295 * logging backend, and usually requires using APIs specific to that backend.
1296 * <p>For the default {@code LoggerFinder} implementation
1297 * using {@code java.util.logging} as its backend, refer to
1298 * {@link java.logging/java.util.logging java.util.logging} for logging configuration.
1299 * For the default {@code LoggerFinder} implementation returning simple loggers
1300 * when the {@code java.logging} module is absent, the configuration
1301 * is implementation dependent.
1302 * <p>
1303 * Usually an application that uses a logging framework will log messages
1304 * through a logger facade defined (or supported) by that framework.
1305 * Applications that wish to use an external framework should log
1306 * through the facade associated with that framework.
1307 * <p>
1308 * A system class that needs to log messages will typically obtain
1309 * a {@link System.Logger} instance to route messages to the logging
1310 * framework selected by the application.
1311 * <p>
1312 * Libraries and classes that only need loggers to produce log messages
1313 * should not attempt to configure loggers by themselves, as that
1314 * would make them dependent from a specific implementation of the
1315 * {@code LoggerFinder} service.
1316 * <p>
1317 * <b>Message Levels and Mapping to backend levels</b>
1318 * <p>
1319 * A logger finder is responsible for mapping from a {@code
1320 * System.Logger.Level} to a level supported by the logging backend it uses.
1321 * <br>The default LoggerFinder using {@code java.util.logging} as the backend
1322 * maps {@code System.Logger} levels to
1323 * {@linkplain java.logging/java.util.logging.Level java.util.logging} levels
1324 * of corresponding severity - as described in {@link Logger.Level
1325 * Logger.Level}.
1326 *
1327 * @see java.lang.System
1328 * @see java.lang.System.Logger
1329 *
1330 * @since 9
1331 */
1332 @SuppressWarnings("doclint:reference") // cross-module links
1333 public abstract static class LoggerFinder {
1334
1335 /**
1336 * Creates a new instance of {@code LoggerFinder}.
1337 *
1338 * @implNote It is recommended that a {@code LoggerFinder} service
1339 * implementation does not perform any heavy initialization in its
1340 * constructor, in order to avoid possible risks of deadlock or class
1341 * loading cycles during the instantiation of the service provider.
1342 */
1343 protected LoggerFinder() {
1344 }
1345
1346 /**
1347 * Returns an instance of {@link Logger Logger}
1348 * for the given {@code module}.
1349 *
1350 * @param name the name of the logger.
1351 * @param module the module for which the logger is being requested.
1352 *
1353 * @return a {@link Logger logger} suitable for use within the given
1354 * module.
1355 * @throws NullPointerException if {@code name} is {@code null} or
1356 * {@code module} is {@code null}.
1357 */
1358 public abstract Logger getLogger(String name, Module module);
1359
1360 /**
1361 * Returns a localizable instance of {@link Logger Logger}
1362 * for the given {@code module}.
1363 * The returned logger will use the provided resource bundle for
1364 * message localization.
1365 *
1366 * @implSpec By default, this method calls {@link
1367 * #getLogger(java.lang.String, java.lang.Module)
1368 * this.getLogger(name, module)} to obtain a logger, then wraps that
1369 * logger in a {@link Logger} instance where all methods that do not
1370 * take a {@link ResourceBundle} as parameter are redirected to one
1371 * which does - passing the given {@code bundle} for
1372 * localization. So for instance, a call to {@link
1373 * Logger#log(Logger.Level, String) Logger.log(Level.INFO, msg)}
1374 * will end up as a call to {@link
1375 * Logger#log(Logger.Level, ResourceBundle, String, Object...)
1376 * Logger.log(Level.INFO, bundle, msg, (Object[])null)} on the wrapped
1377 * logger instance.
1378 * Note however that by default, string messages returned by {@link
1379 * java.util.function.Supplier Supplier<String>} will not be
1380 * localized, as it is assumed that such strings are messages which are
1381 * already constructed, rather than keys in a resource bundle.
1382 * <p>
1383 * An implementation of {@code LoggerFinder} may override this method,
1384 * for example, when the underlying logging backend provides its own
1385 * mechanism for localizing log messages, then such a
1386 * {@code LoggerFinder} would be free to return a logger
1387 * that makes direct use of the mechanism provided by the backend.
1388 *
1389 * @param name the name of the logger.
1390 * @param bundle a resource bundle; can be {@code null}.
1391 * @param module the module for which the logger is being requested.
1392 * @return an instance of {@link Logger Logger} which will use the
1393 * provided resource bundle for message localization.
1394 *
1395 * @throws NullPointerException if {@code name} is {@code null} or
1396 * {@code module} is {@code null}.
1397 */
1398 public Logger getLocalizedLogger(String name, ResourceBundle bundle,
1399 Module module) {
1400 return new LocalizedLoggerWrapper<>(getLogger(name, module), bundle);
1401 }
1402
1403 /**
1404 * Returns the {@code LoggerFinder} instance. There is one
1405 * single system-wide {@code LoggerFinder} instance in
1406 * the Java Runtime. See the class specification of how the
1407 * {@link LoggerFinder LoggerFinder} implementation is located and
1408 * loaded.
1409 *
1410 * @return the {@link LoggerFinder LoggerFinder} instance.
1411 */
1412 public static LoggerFinder getLoggerFinder() {
1413 return accessProvider();
1414 }
1415
1416
1417 private static volatile LoggerFinder service;
1418 static LoggerFinder accessProvider() {
1419 // We do not need to synchronize: LoggerFinderLoader will
1420 // always return the same instance, so if we don't have it,
1421 // just fetch it again.
1422 LoggerFinder finder = service;
1423 if (finder == null) {
1424 finder = LoggerFinderLoader.getLoggerFinder();
1425 if (finder instanceof TemporaryLoggerFinder) return finder;
1426 service = finder;
1427 }
1428 return finder;
1429 }
1430
1431 }
1432
1433
1434 /**
1435 * Returns an instance of {@link Logger Logger} for the caller's
1436 * use.
1437 *
1438 * @implSpec
1439 * Instances returned by this method route messages to loggers
1440 * obtained by calling {@link LoggerFinder#getLogger(java.lang.String,
1441 * java.lang.Module) LoggerFinder.getLogger(name, module)}, where
1442 * {@code module} is the caller's module.
1443 * In cases where {@code System.getLogger} is called from a context where
1444 * there is no caller frame on the stack (e.g when called directly
1445 * from a JNI attached thread), {@code IllegalCallerException} is thrown.
1446 * To obtain a logger in such a context, use an auxiliary class that will
1447 * implicitly be identified as the caller, or use the system {@link
1448 * LoggerFinder#getLoggerFinder() LoggerFinder} to obtain a logger instead.
1449 * Note that doing the latter may eagerly initialize the underlying
1450 * logging system.
1451 *
1452 * @apiNote
1453 * This method may defer calling the {@link
1454 * LoggerFinder#getLogger(java.lang.String, java.lang.Module)
1455 * LoggerFinder.getLogger} method to create an actual logger supplied by
1456 * the logging backend, for instance, to allow loggers to be obtained during
1457 * the system initialization time.
1458 *
1459 * @param name the name of the logger.
1460 * @return an instance of {@link Logger} that can be used by the calling
1461 * class.
1462 * @throws NullPointerException if {@code name} is {@code null}.
1463 * @throws IllegalCallerException if there is no Java caller frame on the
1464 * stack.
1465 *
1466 * @since 9
1467 */
1468 @CallerSensitive
1469 public static Logger getLogger(String name) {
1470 Objects.requireNonNull(name);
1471 final Class<?> caller = Reflection.getCallerClass();
1472 if (caller == null) {
1473 throw new IllegalCallerException("no caller frame");
1474 }
1475 return LazyLoggers.getLogger(name, caller.getModule());
1476 }
1477
1478 /**
1479 * Returns a localizable instance of {@link Logger
1480 * Logger} for the caller's use.
1481 * The returned logger will use the provided resource bundle for message
1482 * localization.
1483 *
1484 * @implSpec
1485 * The returned logger will perform message localization as specified
1486 * by {@link LoggerFinder#getLocalizedLogger(java.lang.String,
1487 * java.util.ResourceBundle, java.lang.Module)
1488 * LoggerFinder.getLocalizedLogger(name, bundle, module)}, where
1489 * {@code module} is the caller's module.
1490 * In cases where {@code System.getLogger} is called from a context where
1491 * there is no caller frame on the stack (e.g when called directly
1492 * from a JNI attached thread), {@code IllegalCallerException} is thrown.
1493 * To obtain a logger in such a context, use an auxiliary class that
1494 * will implicitly be identified as the caller, or use the system {@link
1495 * LoggerFinder#getLoggerFinder() LoggerFinder} to obtain a logger instead.
1496 * Note that doing the latter may eagerly initialize the underlying
1497 * logging system.
1498 *
1499 * @apiNote
1500 * This method is intended to be used after the system is fully initialized.
1501 * This method may trigger the immediate loading and initialization
1502 * of the {@link LoggerFinder} service, which may cause issues if the
1503 * Java Runtime is not ready to initialize the concrete service
1504 * implementation yet.
1505 * System classes which may be loaded early in the boot sequence and
1506 * need to log localized messages should create a logger using
1507 * {@link #getLogger(java.lang.String)} and then use the log methods that
1508 * take a resource bundle as parameter.
1509 *
1510 * @param name the name of the logger.
1511 * @param bundle a resource bundle.
1512 * @return an instance of {@link Logger} which will use the provided
1513 * resource bundle for message localization.
1514 * @throws NullPointerException if {@code name} is {@code null} or
1515 * {@code bundle} is {@code null}.
1516 * @throws IllegalCallerException if there is no Java caller frame on the
1517 * stack.
1518 *
1519 * @since 9
1520 */
1521 @CallerSensitive
1522 public static Logger getLogger(String name, ResourceBundle bundle) {
1523 final ResourceBundle rb = Objects.requireNonNull(bundle);
1524 Objects.requireNonNull(name);
1525 final Class<?> caller = Reflection.getCallerClass();
1526 if (caller == null) {
1527 throw new IllegalCallerException("no caller frame");
1528 }
1529 return LoggerFinder.accessProvider()
1530 .getLocalizedLogger(name, rb, caller.getModule());
1531 }
1532
1533 /**
1534 * Initiates the {@linkplain Runtime##shutdown shutdown sequence} of the Java Virtual
1535 * Machine. This method initiates the shutdown sequence (if it is not already initiated)
1536 * and then blocks indefinitely. This method neither returns nor throws an exception;
1537 * that is, it does not complete either normally or abruptly.
1538 * <p>
1539 * The argument serves as a status code. By convention, a nonzero status code
1540 * indicates abnormal termination.
1541 * <p>
1542 * The call {@code System.exit(n)} is effectively equivalent to the call:
1543 * {@snippet :
1544 * Runtime.getRuntime().exit(n)
1545 * }
1546 *
1547 * @implNote
1548 * The initiation of the shutdown sequence is logged by {@link Runtime#exit(int)}.
1549 *
1550 * @param status exit status.
1551 * @see java.lang.Runtime#exit(int)
1552 */
1553 public static void exit(int status) {
1554 Runtime.getRuntime().exit(status);
1555 }
1556
1557 /**
1558 * Runs the garbage collector in the Java Virtual Machine.
1559 * <p>
1560 * Calling the {@code gc} method suggests that the Java Virtual Machine
1561 * expend effort toward recycling unused objects in order to
1562 * make the memory they currently occupy available for reuse
1563 * by the Java Virtual Machine.
1564 * When control returns from the method call, the Java Virtual Machine
1565 * has made a best effort to reclaim space from all unused objects.
1566 * There is no guarantee that this effort will recycle any particular
1567 * number of unused objects, reclaim any particular amount of space, or
1568 * complete at any particular time, if at all, before the method returns or ever.
1569 * There is also no guarantee that this effort will determine
1570 * the change of reachability in any particular number of objects,
1571 * or that any particular number of {@link java.lang.ref.Reference Reference}
1572 * objects will be cleared and enqueued.
1573 *
1574 * <p>
1575 * The call {@code System.gc()} is effectively equivalent to the
1576 * call:
1577 * <blockquote><pre>
1578 * Runtime.getRuntime().gc()
1579 * </pre></blockquote>
1580 *
1581 * @see java.lang.Runtime#gc()
1582 */
1583 public static void gc() {
1584 Runtime.getRuntime().gc();
1585 }
1586
1587 /**
1588 * Runs the finalization methods of any objects pending finalization.
1589 *
1590 * Calling this method suggests that the Java Virtual Machine expend
1591 * effort toward running the {@code finalize} methods of objects
1592 * that have been found to be discarded but whose {@code finalize}
1593 * methods have not yet been run. When control returns from the
1594 * method call, the Java Virtual Machine has made a best effort to
1595 * complete all outstanding finalizations.
1596 * <p>
1597 * The call {@code System.runFinalization()} is effectively
1598 * equivalent to the call:
1599 * <blockquote><pre>
1600 * Runtime.getRuntime().runFinalization()
1601 * </pre></blockquote>
1602 *
1603 * @deprecated Finalization has been deprecated for removal. See
1604 * {@link java.lang.Object#finalize} for background information and details
1605 * about migration options.
1606 * <p>
1607 * When running in a JVM in which finalization has been disabled or removed,
1608 * no objects will be pending finalization, so this method does nothing.
1609 *
1610 * @see java.lang.Runtime#runFinalization()
1611 * @jls 12.6 Finalization of Class Instances
1612 */
1613 @Deprecated(since="18", forRemoval=true)
1614 @SuppressWarnings("removal")
1615 public static void runFinalization() {
1616 Runtime.getRuntime().runFinalization();
1617 }
1618
1619 /**
1620 * Loads the native library specified by the filename argument. The filename
1621 * argument must be an absolute path name.
1622 *
1623 * If the filename argument, when stripped of any platform-specific library
1624 * prefix, path, and file extension, indicates a library whose name is,
1625 * for example, L, and a native library called L is statically linked
1626 * with the VM, then the JNI_OnLoad_L function exported by the library
1627 * is invoked rather than attempting to load a dynamic library.
1628 * A filename matching the argument does not have to exist in the
1629 * file system.
1630 * See the <a href="{@docRoot}/../specs/jni/index.html"> JNI Specification</a>
1631 * for more details.
1632 *
1633 * Otherwise, the filename argument is mapped to a native library image in
1634 * an implementation-dependent manner.
1635 *
1636 * <p>
1637 * The call {@code System.load(name)} is effectively equivalent
1638 * to the call:
1639 * <blockquote><pre>
1640 * Runtime.getRuntime().load(name)
1641 * </pre></blockquote>
1642 *
1643 * @param filename the file to load.
1644 * @throws UnsatisfiedLinkError if either the filename is not an
1645 * absolute path name, the native library is not statically
1646 * linked with the VM, or the library cannot be mapped to
1647 * a native library image by the host system.
1648 * @throws NullPointerException if {@code filename} is {@code null}
1649 * @throws IllegalCallerException if the caller is in a module that
1650 * does not have native access enabled.
1651 *
1652 * @spec jni/index.html Java Native Interface Specification
1653 * @see java.lang.Runtime#load(java.lang.String)
1654 */
1655 @CallerSensitive
1656 @Restricted
1657 public static void load(String filename) {
1658 Class<?> caller = Reflection.getCallerClass();
1659 Reflection.ensureNativeAccess(caller, System.class, "load", false);
1660 Runtime.getRuntime().load0(caller, filename);
1661 }
1662
1663 /**
1664 * Loads the native library specified by the {@code libname}
1665 * argument. The {@code libname} argument must not contain any platform
1666 * specific prefix, file extension or path. If a native library
1667 * called {@code libname} is statically linked with the VM, then the
1668 * JNI_OnLoad_{@code libname} function exported by the library is invoked.
1669 * See the <a href="{@docRoot}/../specs/jni/index.html"> JNI Specification</a>
1670 * for more details.
1671 *
1672 * Otherwise, the libname argument is loaded from a system library
1673 * location and mapped to a native library image in an
1674 * implementation-dependent manner.
1675 * <p>
1676 * The call {@code System.loadLibrary(name)} is effectively
1677 * equivalent to the call
1678 * <blockquote><pre>
1679 * Runtime.getRuntime().loadLibrary(name)
1680 * </pre></blockquote>
1681 *
1682 * @param libname the name of the library.
1683 * @throws UnsatisfiedLinkError if either the libname argument
1684 * contains a file path, the native library is not statically
1685 * linked with the VM, or the library cannot be mapped to a
1686 * native library image by the host system.
1687 * @throws NullPointerException if {@code libname} is {@code null}
1688 * @throws IllegalCallerException if the caller is in a module that
1689 * does not have native access enabled.
1690 *
1691 * @spec jni/index.html Java Native Interface Specification
1692 * @see java.lang.Runtime#loadLibrary(java.lang.String)
1693 */
1694 @CallerSensitive
1695 @Restricted
1696 public static void loadLibrary(String libname) {
1697 Class<?> caller = Reflection.getCallerClass();
1698 Reflection.ensureNativeAccess(caller, System.class, "loadLibrary", false);
1699 Runtime.getRuntime().loadLibrary0(caller, libname);
1700 }
1701
1702 /**
1703 * Maps a library name into a platform-specific string representing
1704 * a native library.
1705 *
1706 * @param libname the name of the library.
1707 * @return a platform-dependent native library name.
1708 * @throws NullPointerException if {@code libname} is {@code null}
1709 * @see java.lang.System#loadLibrary(java.lang.String)
1710 * @see java.lang.ClassLoader#findLibrary(java.lang.String)
1711 * @since 1.2
1712 */
1713 public static native String mapLibraryName(String libname);
1714
1715 /**
1716 * Create PrintStream for stdout/err based on encoding.
1717 */
1718 private static PrintStream newPrintStream(OutputStream out, String enc) {
1719 if (enc != null) {
1720 return new PrintStream(new BufferedOutputStream(out, 128), true,
1721 Charset.forName(enc, UTF_8.INSTANCE));
1722 }
1723 return new PrintStream(new BufferedOutputStream(out, 128), true);
1724 }
1725
1726 /**
1727 * Logs an exception/error at initialization time to stdout or stderr.
1728 *
1729 * @param printToStderr to print to stderr rather than stdout
1730 * @param printStackTrace to print the stack trace
1731 * @param msg the message to print before the exception, can be {@code null}
1732 * @param e the exception or error
1733 */
1734 private static void logInitException(boolean printToStderr,
1735 boolean printStackTrace,
1736 String msg,
1737 Throwable e) {
1738 if (VM.initLevel() < 1) {
1739 throw new InternalError("system classes not initialized");
1740 }
1741 PrintStream log = (printToStderr) ? err : out;
1742 if (msg != null) {
1743 log.println(msg);
1744 }
1745 if (printStackTrace) {
1746 e.printStackTrace(log);
1747 } else {
1748 log.println(e);
1749 for (Throwable suppressed : e.getSuppressed()) {
1750 log.println("Suppressed: " + suppressed);
1751 }
1752 Throwable cause = e.getCause();
1753 if (cause != null) {
1754 log.println("Caused by: " + cause);
1755 }
1756 }
1757 }
1758
1759 /**
1760 * Create the Properties object from a map - masking out system properties
1761 * that are not intended for public access.
1762 */
1763 private static Properties createProperties(Map<String, String> initialProps) {
1764 Properties properties = new Properties(initialProps.size());
1765 for (var entry : initialProps.entrySet()) {
1766 String prop = entry.getKey();
1767 switch (prop) {
1768 // Do not add private system properties to the Properties
1769 case "sun.nio.MaxDirectMemorySize":
1770 case "sun.nio.PageAlignDirectMemory":
1771 // used by java.lang.Integer.IntegerCache
1772 case "java.lang.Integer.IntegerCache.high":
1773 // used by sun.launcher.LauncherHelper
1774 case "sun.java.launcher.diag":
1775 // used by jdk.internal.loader.ClassLoaders
1776 case "jdk.boot.class.path.append":
1777 break;
1778 default:
1779 properties.put(prop, entry.getValue());
1780 }
1781 }
1782 return properties;
1783 }
1784
1785 /**
1786 * Initialize the system class. Called after thread initialization.
1787 */
1788 private static void initPhase1() {
1789
1790 // register the shared secrets - do this first, since SystemProps.initProperties
1791 // might initialize CharsetDecoders that rely on it
1792 setJavaLangAccess();
1793
1794 // VM might invoke JNU_NewStringPlatform() to set those encoding
1795 // sensitive properties (user.home, user.name, boot.class.path, etc.)
1796 // during "props" initialization.
1797 // The charset is initialized in System.c and does not depend on the Properties.
1798 Map<String, String> tempProps = SystemProps.initProperties();
1799 VersionProps.init(tempProps);
1800
1801 // There are certain system configurations that may be controlled by
1802 // VM options such as the maximum amount of direct memory and
1803 // Integer cache size used to support the object identity semantics
1804 // of autoboxing. Typically, the library will obtain these values
1805 // from the properties set by the VM. If the properties are for
1806 // internal implementation use only, these properties should be
1807 // masked from the system properties.
1808 //
1809 // Save a private copy of the system properties object that
1810 // can only be accessed by the internal implementation.
1811 VM.saveProperties(tempProps);
1812 props = createProperties(tempProps);
1813
1814 // Check if sun.jnu.encoding is supported. If not, replace it with UTF-8.
1815 var jnuEncoding = props.getProperty("sun.jnu.encoding");
1816 if (jnuEncoding == null || !Charset.isSupported(jnuEncoding)) {
1817 notSupportedJnuEncoding = jnuEncoding == null ? "null" : jnuEncoding;
1818 props.setProperty("sun.jnu.encoding", "UTF-8");
1819 }
1820
1821 StaticProperty.javaHome(); // Load StaticProperty to cache the property values
1822
1823 lineSeparator = props.getProperty("line.separator");
1824
1825 FileInputStream fdIn = new In(FileDescriptor.in);
1826 FileOutputStream fdOut = new Out(FileDescriptor.out);
1827 FileOutputStream fdErr = new Out(FileDescriptor.err);
1828 initialIn = new BufferedInputStream(fdIn);
1829 setIn0(initialIn);
1830 // stdout/err.encoding are set when the VM is associated with the terminal,
1831 // thus they are equivalent to Console.charset(), otherwise the encodings
1832 // of those properties default to native.encoding
1833 setOut0(newPrintStream(fdOut, props.getProperty("stdout.encoding")));
1834 initialErr = newPrintStream(fdErr, props.getProperty("stderr.encoding"));
1835 setErr0(initialErr);
1836
1837 // Setup Java signal handlers for HUP, TERM, and INT (where available).
1838 Terminator.setup();
1839
1840 // Initialize any miscellaneous operating system settings that need to be
1841 // set for the class libraries. Currently this is no-op everywhere except
1842 // for Windows where the process-wide error mode is set before the java.io
1843 // classes are used.
1844 VM.initializeOSEnvironment();
1845
1846 // start Finalizer and Reference Handler threads
1847 SharedSecrets.getJavaLangRefAccess().startThreads();
1848
1849 // system properties, java.lang and other core classes are now initialized
1850 VM.initLevel(1);
1851 }
1852
1853 /**
1854 * System.in.
1855 */
1856 private static class In extends FileInputStream {
1857 In(FileDescriptor fd) {
1858 super(fd);
1859 }
1860
1861 @Override
1862 public int read() throws IOException {
1863 boolean attempted = Blocker.begin();
1864 try {
1865 return super.read();
1866 } finally {
1867 Blocker.end(attempted);
1868 }
1869 }
1870
1871 @Override
1872 public int read(byte[] b) throws IOException {
1873 boolean attempted = Blocker.begin();
1874 try {
1875 return super.read(b);
1876 } finally {
1877 Blocker.end(attempted);
1878 }
1879 }
1880
1881 @Override
1882 public int read(byte[] b, int off, int len) throws IOException {
1883 boolean attempted = Blocker.begin();
1884 try {
1885 return super.read(b, off, len);
1886 } finally {
1887 Blocker.end(attempted);
1888 }
1889 }
1890 }
1891
1892 /**
1893 * System.out/System.err wrap this output stream.
1894 */
1895 private static class Out extends FileOutputStream {
1896 Out(FileDescriptor fd) {
1897 super(fd);
1898 }
1899
1900 @Override
1901 public void write(int b) throws IOException {
1902 boolean attempted = Blocker.begin();
1903 try {
1904 super.write(b);
1905 } finally {
1906 Blocker.end(attempted);
1907 }
1908 }
1909
1910 @Override
1911 public void write(byte[] b) throws IOException {
1912 boolean attempted = Blocker.begin();
1913 try {
1914 super.write(b);
1915 } finally {
1916 Blocker.end(attempted);
1917 }
1918 }
1919
1920 @Override
1921 public void write(byte[] b, int off, int len) throws IOException {
1922 boolean attempted = Blocker.begin();
1923 try {
1924 super.write(b, off, len);
1925 } finally {
1926 Blocker.end(attempted);
1927 }
1928 }
1929 }
1930
1931 // @see #initPhase2()
1932 static ModuleLayer bootLayer;
1933
1934 /*
1935 * Invoked by VM. Phase 2 module system initialization.
1936 * Only classes in java.base can be loaded in this phase.
1937 *
1938 * @param printToStderr print exceptions to stderr rather than stdout
1939 * @param printStackTrace print stack trace when exception occurs
1940 *
1941 * @return JNI_OK for success, JNI_ERR for failure
1942 */
1943 private static int initPhase2(boolean printToStderr, boolean printStackTrace) {
1944
1945 try {
1946 bootLayer = ModuleBootstrap.boot();
1947 } catch (Exception | Error e) {
1948 logInitException(printToStderr, printStackTrace,
1949 "Error occurred during initialization of boot layer", e);
1950 return -1; // JNI_ERR
1951 }
1952
1953 // module system initialized
1954 VM.initLevel(2);
1955
1956 return 0; // JNI_OK
1957 }
1958
1959 /*
1960 * Invoked by VM. Phase 3 is the final system initialization:
1961 * 1. set system class loader
1962 * 2. set TCCL
1963 *
1964 * This method must be called after the module system initialization.
1965 */
1966 private static void initPhase3() {
1967
1968 // Emit a warning if java.io.tmpdir is set via the command line
1969 // to a directory that doesn't exist
1970 if (SystemProps.isBadIoTmpdir()) {
1971 System.err.println("WARNING: java.io.tmpdir directory does not exist");
1972 }
1973
1974 String smProp = System.getProperty("java.security.manager");
1975 if (smProp != null) {
1976 switch (smProp) {
1977 case "disallow":
1978 break;
1979 case "allow":
1980 case "":
1981 case "default":
1982 default:
1983 throw new Error("A command line option has attempted to allow or enable the Security Manager."
1984 + " Enabling a Security Manager is not supported.");
1985 }
1986 }
1987
1988 // Emit a warning if `sun.jnu.encoding` is not supported.
1989 if (notSupportedJnuEncoding != null) {
1990 System.err.println(
1991 "WARNING: The encoding of the underlying platform's" +
1992 " file system is not supported: " +
1993 notSupportedJnuEncoding);
1994 }
1995
1996 // initializing the system class loader
1997 VM.initLevel(3);
1998
1999 // system class loader initialized
2000 ClassLoader scl = ClassLoader.initSystemClassLoader();
2001
2002 // set TCCL
2003 Thread.currentThread().setContextClassLoader(scl);
2004
2005 // system is fully initialized
2006 VM.initLevel(4);
2007 }
2008
2009 private static void setJavaLangAccess() {
2010 // Allow privileged classes outside of java.lang
2011 SharedSecrets.setJavaLangAccess(new JavaLangAccess() {
2012 public List<Method> getDeclaredPublicMethods(Class<?> klass, String name, Class<?>... parameterTypes) {
2013 return klass.getDeclaredPublicMethods(name, parameterTypes);
2014 }
2015 public Method findMethod(Class<?> klass, boolean publicOnly, String name, Class<?>... parameterTypes) {
2016 return klass.findMethod(publicOnly, name, parameterTypes);
2017 }
2018 public jdk.internal.reflect.ConstantPool getConstantPool(Class<?> klass) {
2019 return klass.getConstantPool();
2020 }
2021 public boolean casAnnotationType(Class<?> klass, AnnotationType oldType, AnnotationType newType) {
2022 return klass.casAnnotationType(oldType, newType);
2023 }
2024 public AnnotationType getAnnotationType(Class<?> klass) {
2025 return klass.getAnnotationType();
2026 }
2027 public Map<Class<? extends Annotation>, Annotation> getDeclaredAnnotationMap(Class<?> klass) {
2028 return klass.getDeclaredAnnotationMap();
2029 }
2030 public byte[] getRawClassAnnotations(Class<?> klass) {
2031 return klass.getRawAnnotations();
2032 }
2033 public byte[] getRawClassTypeAnnotations(Class<?> klass) {
2034 return klass.getRawTypeAnnotations();
2035 }
2036 public byte[] getRawExecutableTypeAnnotations(Executable executable) {
2037 return Class.getExecutableTypeAnnotationBytes(executable);
2038 }
2039 public int getClassFileAccessFlags(Class<?> klass) {
2040 return klass.getClassFileAccessFlags();
2041 }
2042 public <E extends Enum<E>>
2043 E[] getEnumConstantsShared(Class<E> klass) {
2044 return klass.getEnumConstantsShared();
2045 }
2046 public void blockedOn(Interruptible b) {
2047 Thread.currentThread().blockedOn(b);
2048 }
2049 public void registerShutdownHook(int slot, boolean registerShutdownInProgress, Runnable hook) {
2050 Shutdown.add(slot, registerShutdownInProgress, hook);
2051 }
2052 @SuppressWarnings("removal")
2053 public void invokeFinalize(Object o) throws Throwable {
2054 o.finalize();
2055 }
2056 public ConcurrentHashMap<?, ?> createOrGetClassLoaderValueMap(ClassLoader cl) {
2057 return cl.createOrGetClassLoaderValueMap();
2058 }
2059 public Class<?> defineClass(ClassLoader loader, String name, byte[] b, ProtectionDomain pd, String source) {
2060 return ClassLoader.defineClass1(loader, name, b, 0, b.length, pd, source);
2061 }
2062 public Class<?> defineClass(ClassLoader loader, Class<?> lookup, String name, byte[] b, ProtectionDomain pd,
2063 boolean initialize, int flags, Object classData) {
2064 return ClassLoader.defineClass0(loader, lookup, name, b, 0, b.length, pd, initialize, flags, classData);
2065 }
2066 public Class<?> findBootstrapClassOrNull(String name) {
2067 return ClassLoader.findBootstrapClassOrNull(name);
2068 }
2069 public Package definePackage(ClassLoader cl, String name, Module module) {
2070 return cl.definePackage(name, module);
2071 }
2072 public Module defineModule(ClassLoader loader,
2073 ModuleDescriptor descriptor,
2074 URI uri) {
2075 return new Module(null, loader, descriptor, uri);
2076 }
2077 public Module defineUnnamedModule(ClassLoader loader) {
2078 return new Module(loader);
2079 }
2080 public void addReads(Module m1, Module m2) {
2081 m1.implAddReads(m2);
2082 }
2083 public void addReadsAllUnnamed(Module m) {
2084 m.implAddReadsAllUnnamed();
2085 }
2086 public void addExports(Module m, String pn) {
2087 m.implAddExports(pn);
2088 }
2089 public void addExports(Module m, String pn, Module other) {
2090 m.implAddExports(pn, other);
2091 }
2092 public void addExportsToAllUnnamed(Module m, String pn) {
2093 m.implAddExportsToAllUnnamed(pn);
2094 }
2095 public void addOpens(Module m, String pn, Module other) {
2096 m.implAddOpens(pn, other);
2097 }
2098 public void addOpensToAllUnnamed(Module m, String pn) {
2099 m.implAddOpensToAllUnnamed(pn);
2100 }
2101 public void addUses(Module m, Class<?> service) {
2102 m.implAddUses(service);
2103 }
2104 public boolean isReflectivelyExported(Module m, String pn, Module other) {
2105 return m.isReflectivelyExported(pn, other);
2106 }
2107 public boolean isReflectivelyOpened(Module m, String pn, Module other) {
2108 return m.isReflectivelyOpened(pn, other);
2109 }
2110 public void addEnableNativeAccess(Module m) {
2111 m.implAddEnableNativeAccess();
2112 }
2113 public boolean addEnableNativeAccess(ModuleLayer layer, String name) {
2114 return layer.addEnableNativeAccess(name);
2115 }
2116 public void addEnableNativeAccessToAllUnnamed() {
2117 Module.addEnableNativeAccessToAllUnnamed();
2118 }
2119 public void ensureNativeAccess(Module m, Class<?> owner, String methodName, Class<?> currentClass, boolean jni) {
2120 m.ensureNativeAccess(owner, methodName, currentClass, jni);
2121 }
2122 public boolean isStaticallyExported(Module m, String pn, Module other) {
2123 return m.isStaticallyExported(pn, other);
2124 }
2125 public boolean isStaticallyOpened(Module m, String pn, Module other) {
2126 return m.isStaticallyOpened(pn, other);
2127 }
2128 public boolean isFinalMutationEnabled(Module m) {
2129 return m.isFinalMutationEnabled();
2130 }
2131 public boolean tryEnableFinalMutation(Module m) {
2132 return m.tryEnableFinalMutation();
2133 }
2134 public void addEnableFinalMutationToAllUnnamed() {
2135 Module.addEnableFinalMutationToAllUnnamed();
2136 }
2137 public ServicesCatalog getServicesCatalog(ModuleLayer layer) {
2138 return layer.getServicesCatalog();
2139 }
2140 public void bindToLoader(ModuleLayer layer, ClassLoader loader) {
2141 layer.bindToLoader(loader);
2142 }
2143 public Stream<ModuleLayer> layers(ModuleLayer layer) {
2144 return layer.layers();
2145 }
2146 public Stream<ModuleLayer> layers(ClassLoader loader) {
2147 return ModuleLayer.layers(loader);
2148 }
2149
2150 public int countPositives(byte[] bytes, int offset, int length) {
2151 return StringCoding.countPositives(bytes, offset, length);
2152 }
2153
2154 public int countNonZeroAscii(String s) {
2155 return StringCoding.countNonZeroAscii(s);
2156 }
2157
2158 public String uncheckedNewStringWithLatin1Bytes(byte[] bytes) {
2159 return String.newStringWithLatin1Bytes(bytes);
2160 }
2161
2162 public String uncheckedNewStringOrThrow(byte[] bytes, Charset cs) throws CharacterCodingException {
2163 return String.newStringOrThrow(bytes, cs);
2164 }
2165
2166 public char uncheckedGetUTF16Char(byte[] bytes, int index) {
2167 return StringUTF16.getChar(bytes, index);
2168 }
2169
2170 public void uncheckedPutCharUTF16(byte[] bytes, int index, int ch) {
2171 StringUTF16.putChar(bytes, index, ch);
2172 }
2173
2174 public byte[] uncheckedGetBytesOrThrow(String s, Charset cs) throws CharacterCodingException {
2175 return String.getBytesOrThrow(s, cs);
2176 }
2177
2178 public byte[] getBytesUTF8OrThrow(String s) throws CharacterCodingException {
2179 return String.getBytesUTF8OrThrow(s);
2180 }
2181
2182 public void inflateBytesToChars(byte[] src, int srcOff, char[] dst, int dstOff, int len) {
2183 StringLatin1.inflate(src, srcOff, dst, dstOff, len);
2184 }
2185
2186 public int decodeASCII(byte[] src, int srcOff, char[] dst, int dstOff, int len) {
2187 return String.decodeASCII(src, srcOff, dst, dstOff, len);
2188 }
2189
2190 public int encodeASCII(char[] sa, int sp, byte[] da, int dp, int len) {
2191 return StringCoding.encodeAsciiArray(sa, sp, da, dp, len);
2192 }
2193
2194 public InputStream initialSystemIn() {
2195 return initialIn;
2196 }
2197
2198 public PrintStream initialSystemErr() {
2199 return initialErr;
2200 }
2201
2202 public void setCause(Throwable t, Throwable cause) {
2203 t.setCause(cause);
2204 }
2205
2206 public ProtectionDomain protectionDomain(Class<?> c) {
2207 return c.getProtectionDomain();
2208 }
2209
2210 public MethodHandle stringConcatHelper(String name, MethodType methodType) {
2211 return StringConcatHelper.lookupStatic(name, methodType);
2212 }
2213
2214 public Object uncheckedStringConcat1(String[] constants) {
2215 return new StringConcatHelper.Concat1(constants);
2216 }
2217
2218 public byte stringInitCoder() {
2219 return String.COMPACT_STRINGS ? String.LATIN1 : String.UTF16;
2220 }
2221
2222 public byte stringCoder(String str) {
2223 return str.coder();
2224 }
2225
2226 public String join(String prefix, String suffix, String delimiter, String[] elements, int size) {
2227 return String.join(prefix, suffix, delimiter, elements, size);
2228 }
2229
2230 public String concat(String prefix, Object value, String suffix) {
2231 return StringConcatHelper.concat(prefix, value, suffix);
2232 }
2233
2234 public Object classData(Class<?> c) {
2235 return c.getClassData();
2236 }
2237
2238 @Override
2239 public NativeLibraries nativeLibrariesFor(ClassLoader loader) {
2240 return ClassLoader.nativeLibrariesFor(loader);
2241 }
2242
2243 public Thread[] getAllThreads() {
2244 return Thread.getAllThreads();
2245 }
2246
2247 public ThreadContainer threadContainer(Thread thread) {
2248 return thread.threadContainer();
2249 }
2250
2251 public void start(Thread thread, ThreadContainer container) {
2252 thread.start(container);
2253 }
2254
2255 public StackableScope headStackableScope(Thread thread) {
2256 return thread.headStackableScopes();
2257 }
2258
2259 public void setHeadStackableScope(StackableScope scope) {
2260 Thread.setHeadStackableScope(scope);
2261 }
2262
2263 public Thread currentCarrierThread() {
2264 return Thread.currentCarrierThread();
2265 }
2266
2267 public <T> T getCarrierThreadLocal(CarrierThreadLocal<T> local) {
2268 return ((ThreadLocal<T>)local).getCarrierThreadLocal();
2269 }
2270
2271 public <T> void setCarrierThreadLocal(CarrierThreadLocal<T> local, T value) {
2272 ((ThreadLocal<T>)local).setCarrierThreadLocal(value);
2273 }
2274
2275 public void removeCarrierThreadLocal(CarrierThreadLocal<?> local) {
2276 ((ThreadLocal<?>)local).removeCarrierThreadLocal();
2277 }
2278
2279 public Object[] scopedValueCache() {
2280 return Thread.scopedValueCache();
2281 }
2282
2283 public void setScopedValueCache(Object[] cache) {
2284 Thread.setScopedValueCache(cache);
2285 }
2286
2287 public Object scopedValueBindings() {
2288 return Thread.scopedValueBindings();
2289 }
2290
2291 public long nativeThreadID(Thread thread) {
2292 return thread.nativeThreadID();
2293 }
2294
2295 public void setThreadNativeID(long id) {
2296 Thread.currentThread().setNativeThreadID(id);
2297 }
2298
2299 public Continuation getContinuation(Thread thread) {
2300 return thread.getContinuation();
2301 }
2302
2303 public void setContinuation(Thread thread, Continuation continuation) {
2304 thread.setContinuation(continuation);
2305 }
2306
2307 public ContinuationScope virtualThreadContinuationScope() {
2308 return VirtualThread.continuationScope();
2309 }
2310
2311 public void parkVirtualThread() {
2312 Thread thread = Thread.currentThread();
2313 if (thread instanceof BaseVirtualThread vthread) {
2314 vthread.park();
2315 } else {
2316 throw new WrongThreadException();
2317 }
2318 }
2319
2320 public void parkVirtualThread(long nanos) {
2321 Thread thread = Thread.currentThread();
2322 if (thread instanceof BaseVirtualThread vthread) {
2323 vthread.parkNanos(nanos);
2324 } else {
2325 throw new WrongThreadException();
2326 }
2327 }
2328
2329 public void unparkVirtualThread(Thread thread) {
2330 if (thread instanceof BaseVirtualThread vthread) {
2331 vthread.unpark();
2332 } else {
2333 throw new IllegalArgumentException();
2334 }
2335 }
2336
2337 public Thread.VirtualThreadScheduler builtinVirtualThreadScheduler() {
2338 return VirtualThread.builtinScheduler(true);
2339 }
2340
2341 public Thread.VirtualThreadScheduler defaultVirtualThreadScheduler() {
2342 return VirtualThread.defaultScheduler();
2343 }
2344
2345 public StackWalker newStackWalkerInstance(Set<StackWalker.Option> options,
2346 ContinuationScope contScope,
2347 Continuation continuation) {
2348 return StackWalker.newInstance(options, null, contScope, continuation);
2349 }
2350
2351 public String getLoaderNameID(ClassLoader loader) {
2352 return loader != null ? loader.nameAndId() : "null";
2353 }
2354
2355 @Override
2356 public void copyToSegmentRaw(String string, MemorySegment segment, long offset, int srcIndex, int srcLength) {
2357 string.copyToSegmentRaw(segment, offset, srcIndex, srcLength);
2358 }
2359
2360 @Override
2361 public boolean bytesCompatible(String string, Charset charset, int srcIndex, int numChars) {
2362 return string.bytesCompatible(charset, srcIndex, numChars);
2363 }
2364
2365 @Override
2366 public void finishInit(StackTraceElement[] stackTrace) {
2367 StackTraceElement.finishInit(stackTrace);
2368 }
2369 });
2370 }
2371 }