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