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