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