1 /* 2 * Copyright (c) 1994, 2014, 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.*; 28 import java.lang.reflect.Executable; 29 import java.lang.annotation.Annotation; 30 import java.security.AccessControlContext; 31 import java.util.Properties; 32 import java.util.PropertyPermission; 33 import java.util.Map; 34 import java.security.AccessController; 35 import java.security.PrivilegedAction; 36 import java.nio.channels.Channel; 37 import java.nio.channels.spi.SelectorProvider; 38 import java.util.Objects; 39 import java.util.ResourceBundle; 40 import java.security.Permission; 41 import java.util.Arrays; 42 import java.util.ServiceConfigurationError; 43 import java.util.ServiceLoader; 44 import java.util.function.Supplier; 45 import sun.util.logger.JdkLoggerProvider; 46 import sun.nio.ch.Interruptible; 47 import sun.reflect.CallerSensitive; 48 import sun.reflect.Reflection; 49 import sun.security.util.SecurityConstants; 50 import sun.reflect.annotation.AnnotationType; 51 import jdk.internal.HotSpotIntrinsicCandidate; 52 import jdk.internal.misc.JavaLangAccess;; 53 import jdk.internal.misc.SharedSecrets;; 54 import sun.util.logger.BootstrapLogger; 55 import sun.util.logger.LazyLoggers; 56 import sun.util.logger.LocalizedLoggerWrapper; 57 58 /** 59 * The <code>System</code> class contains several useful class fields 60 * and methods. It cannot be instantiated. 61 * 62 * <p>Among the facilities provided by the <code>System</code> class 63 * are standard input, standard output, and error output streams; 64 * access to externally defined properties and environment 65 * variables; a means of loading files and libraries; and a utility 66 * method for quickly copying a portion of an array. 67 * 68 * @author unascribed 69 * @since 1.0 70 */ 71 public final class System { 72 73 /* register the natives via the static initializer. 74 * 75 * VM will invoke the initializeSystemClass method to complete 76 * the initialization for this class separated from clinit. 77 * Note that to use properties set by the VM, see the constraints 78 * described in the initializeSystemClass method. 79 */ 80 private static native void registerNatives(); 81 static { 82 registerNatives(); 83 } 84 85 /** Don't let anyone instantiate this class */ 86 private System() { 87 } 88 89 /** 90 * The "standard" input stream. This stream is already 91 * open and ready to supply input data. Typically this stream 92 * corresponds to keyboard input or another input source specified by 93 * the host environment or user. 94 */ 95 public static final InputStream in = null; 96 97 /** 98 * The "standard" output stream. This stream is already 99 * open and ready to accept output data. Typically this stream 100 * corresponds to display output or another output destination 101 * specified by the host environment or user. 102 * <p> 103 * For simple stand-alone Java applications, a typical way to write 104 * a line of output data is: 105 * <blockquote><pre> 106 * System.out.println(data) 107 * </pre></blockquote> 108 * <p> 109 * See the <code>println</code> methods in class <code>PrintStream</code>. 110 * 111 * @see java.io.PrintStream#println() 112 * @see java.io.PrintStream#println(boolean) 113 * @see java.io.PrintStream#println(char) 114 * @see java.io.PrintStream#println(char[]) 115 * @see java.io.PrintStream#println(double) 116 * @see java.io.PrintStream#println(float) 117 * @see java.io.PrintStream#println(int) 118 * @see java.io.PrintStream#println(long) 119 * @see java.io.PrintStream#println(java.lang.Object) 120 * @see java.io.PrintStream#println(java.lang.String) 121 */ 122 public static final PrintStream out = null; 123 124 /** 125 * The "standard" error output stream. This stream is already 126 * open and ready to accept output data. 127 * <p> 128 * Typically this stream corresponds to display output or another 129 * output destination specified by the host environment or user. By 130 * convention, this output stream is used to display error messages 131 * or other information that should come to the immediate attention 132 * of a user even if the principal output stream, the value of the 133 * variable <code>out</code>, has been redirected to a file or other 134 * destination that is typically not continuously monitored. 135 */ 136 public static final PrintStream err = null; 137 138 /* The security manager for the system. 139 */ 140 private static volatile SecurityManager security = null; 141 142 /** 143 * Reassigns the "standard" input stream. 144 * 145 * <p>First, if there is a security manager, its <code>checkPermission</code> 146 * method is called with a <code>RuntimePermission("setIO")</code> permission 147 * to see if it's ok to reassign the "standard" input stream. 148 * 149 * @param in the new standard input stream. 150 * 151 * @throws SecurityException 152 * if a security manager exists and its 153 * <code>checkPermission</code> method doesn't allow 154 * reassigning of the standard input stream. 155 * 156 * @see SecurityManager#checkPermission 157 * @see java.lang.RuntimePermission 158 * 159 * @since 1.1 160 */ 161 public static void setIn(InputStream in) { 162 checkIO(); 163 setIn0(in); 164 } 165 166 /** 167 * Reassigns the "standard" output stream. 168 * 169 * <p>First, if there is a security manager, its <code>checkPermission</code> 170 * method is called with a <code>RuntimePermission("setIO")</code> permission 171 * to see if it's ok to reassign the "standard" output stream. 172 * 173 * @param out the new standard output stream 174 * 175 * @throws SecurityException 176 * if a security manager exists and its 177 * <code>checkPermission</code> method doesn't allow 178 * reassigning of the standard output stream. 179 * 180 * @see SecurityManager#checkPermission 181 * @see java.lang.RuntimePermission 182 * 183 * @since 1.1 184 */ 185 public static void setOut(PrintStream out) { 186 checkIO(); 187 setOut0(out); 188 } 189 190 /** 191 * Reassigns the "standard" error output stream. 192 * 193 * <p>First, if there is a security manager, its <code>checkPermission</code> 194 * method is called with a <code>RuntimePermission("setIO")</code> permission 195 * to see if it's ok to reassign the "standard" error output stream. 196 * 197 * @param err the new standard error output stream. 198 * 199 * @throws SecurityException 200 * if a security manager exists and its 201 * <code>checkPermission</code> method doesn't allow 202 * reassigning of the standard error output stream. 203 * 204 * @see SecurityManager#checkPermission 205 * @see java.lang.RuntimePermission 206 * 207 * @since 1.1 208 */ 209 public static void setErr(PrintStream err) { 210 checkIO(); 211 setErr0(err); 212 } 213 214 private static volatile Console cons = null; 215 /** 216 * Returns the unique {@link java.io.Console Console} object associated 217 * with the current Java virtual machine, if any. 218 * 219 * @return The system console, if any, otherwise {@code null}. 220 * 221 * @since 1.6 222 */ 223 public static Console console() { 224 if (cons == null) { 225 synchronized (System.class) { 226 cons = SharedSecrets.getJavaIOAccess().console(); 227 } 228 } 229 return cons; 230 } 231 232 /** 233 * Returns the channel inherited from the entity that created this 234 * Java virtual machine. 235 * 236 * <p> This method returns the channel obtained by invoking the 237 * {@link java.nio.channels.spi.SelectorProvider#inheritedChannel 238 * inheritedChannel} method of the system-wide default 239 * {@link java.nio.channels.spi.SelectorProvider} object. </p> 240 * 241 * <p> In addition to the network-oriented channels described in 242 * {@link java.nio.channels.spi.SelectorProvider#inheritedChannel 243 * inheritedChannel}, this method may return other kinds of 244 * channels in the future. 245 * 246 * @return The inherited channel, if any, otherwise {@code null}. 247 * 248 * @throws IOException 249 * If an I/O error occurs 250 * 251 * @throws SecurityException 252 * If a security manager is present and it does not 253 * permit access to the channel. 254 * 255 * @since 1.5 256 */ 257 public static Channel inheritedChannel() throws IOException { 258 return SelectorProvider.provider().inheritedChannel(); 259 } 260 261 private static void checkIO() { 262 SecurityManager sm = getSecurityManager(); 263 if (sm != null) { 264 sm.checkPermission(new RuntimePermission("setIO")); 265 } 266 } 267 268 private static native void setIn0(InputStream in); 269 private static native void setOut0(PrintStream out); 270 private static native void setErr0(PrintStream err); 271 272 /** 273 * Sets the System security. 274 * 275 * <p> If there is a security manager already installed, this method first 276 * calls the security manager's <code>checkPermission</code> method 277 * with a <code>RuntimePermission("setSecurityManager")</code> 278 * permission to ensure it's ok to replace the existing 279 * security manager. 280 * This may result in throwing a <code>SecurityException</code>. 281 * 282 * <p> Otherwise, the argument is established as the current 283 * security manager. If the argument is <code>null</code> and no 284 * security manager has been established, then no action is taken and 285 * the method simply returns. 286 * 287 * @param s the security manager. 288 * @exception SecurityException if the security manager has already 289 * been set and its <code>checkPermission</code> method 290 * doesn't allow it to be replaced. 291 * @see #getSecurityManager 292 * @see SecurityManager#checkPermission 293 * @see java.lang.RuntimePermission 294 */ 295 public static 296 void setSecurityManager(final SecurityManager s) { 297 try { 298 s.checkPackageAccess("java.lang"); 299 } catch (Exception e) { 300 // no-op 301 } 302 setSecurityManager0(s); 303 } 304 305 private static synchronized 306 void setSecurityManager0(final SecurityManager s) { 307 SecurityManager sm = getSecurityManager(); 308 if (sm != null) { 309 // ask the currently installed security manager if we 310 // can replace it. 311 sm.checkPermission(new RuntimePermission 312 ("setSecurityManager")); 313 } 314 315 if ((s != null) && (s.getClass().getClassLoader() != null)) { 316 // New security manager class is not on bootstrap classpath. 317 // Cause policy to get initialized before we install the new 318 // security manager, in order to prevent infinite loops when 319 // trying to initialize the policy (which usually involves 320 // accessing some security and/or system properties, which in turn 321 // calls the installed security manager's checkPermission method 322 // which will loop infinitely if there is a non-system class 323 // (in this case: the new security manager class) on the stack). 324 AccessController.doPrivileged(new PrivilegedAction<>() { 325 public Object run() { 326 s.getClass().getProtectionDomain().implies 327 (SecurityConstants.ALL_PERMISSION); 328 return null; 329 } 330 }); 331 } 332 333 security = s; 334 } 335 336 /** 337 * Gets the system security interface. 338 * 339 * @return if a security manager has already been established for the 340 * current application, then that security manager is returned; 341 * otherwise, <code>null</code> is returned. 342 * @see #setSecurityManager 343 */ 344 public static SecurityManager getSecurityManager() { 345 return security; 346 } 347 348 /** 349 * Returns the current time in milliseconds. Note that 350 * while the unit of time of the return value is a millisecond, 351 * the granularity of the value depends on the underlying 352 * operating system and may be larger. For example, many 353 * operating systems measure time in units of tens of 354 * milliseconds. 355 * 356 * <p> See the description of the class <code>Date</code> for 357 * a discussion of slight discrepancies that may arise between 358 * "computer time" and coordinated universal time (UTC). 359 * 360 * @return the difference, measured in milliseconds, between 361 * the current time and midnight, January 1, 1970 UTC. 362 * @see java.util.Date 363 */ 364 @HotSpotIntrinsicCandidate 365 public static native long currentTimeMillis(); 366 367 /** 368 * Returns the current value of the running Java Virtual Machine's 369 * high-resolution time source, in nanoseconds. 370 * 371 * <p>This method can only be used to measure elapsed time and is 372 * not related to any other notion of system or wall-clock time. 373 * The value returned represents nanoseconds since some fixed but 374 * arbitrary <i>origin</i> time (perhaps in the future, so values 375 * may be negative). The same origin is used by all invocations of 376 * this method in an instance of a Java virtual machine; other 377 * virtual machine instances are likely to use a different origin. 378 * 379 * <p>This method provides nanosecond precision, but not necessarily 380 * nanosecond resolution (that is, how frequently the value changes) 381 * - no guarantees are made except that the resolution is at least as 382 * good as that of {@link #currentTimeMillis()}. 383 * 384 * <p>Differences in successive calls that span greater than 385 * approximately 292 years (2<sup>63</sup> nanoseconds) will not 386 * correctly compute elapsed time due to numerical overflow. 387 * 388 * <p>The values returned by this method become meaningful only when 389 * the difference between two such values, obtained within the same 390 * instance of a Java virtual machine, is computed. 391 * 392 * <p>For example, to measure how long some code takes to execute: 393 * <pre> {@code 394 * long startTime = System.nanoTime(); 395 * // ... the code being measured ... 396 * long elapsedNanos = System.nanoTime() - startTime;}</pre> 397 * 398 * <p>To compare elapsed time against a timeout, use <pre> {@code 399 * if (System.nanoTime() - startTime >= timeoutNanos) ...}</pre> 400 * instead of <pre> {@code 401 * if (System.nanoTime() >= startTime + timeoutNanos) ...}</pre> 402 * because of the possibility of numerical overflow. 403 * 404 * @return the current value of the running Java Virtual Machine's 405 * high-resolution time source, in nanoseconds 406 * @since 1.5 407 */ 408 @HotSpotIntrinsicCandidate 409 public static native long nanoTime(); 410 411 /** 412 * Copies an array from the specified source array, beginning at the 413 * specified position, to the specified position of the destination array. 414 * A subsequence of array components are copied from the source 415 * array referenced by <code>src</code> to the destination array 416 * referenced by <code>dest</code>. The number of components copied is 417 * equal to the <code>length</code> argument. The components at 418 * positions <code>srcPos</code> through 419 * <code>srcPos+length-1</code> in the source array are copied into 420 * positions <code>destPos</code> through 421 * <code>destPos+length-1</code>, respectively, of the destination 422 * array. 423 * <p> 424 * If the <code>src</code> and <code>dest</code> arguments refer to the 425 * same array object, then the copying is performed as if the 426 * components at positions <code>srcPos</code> through 427 * <code>srcPos+length-1</code> were first copied to a temporary 428 * array with <code>length</code> components and then the contents of 429 * the temporary array were copied into positions 430 * <code>destPos</code> through <code>destPos+length-1</code> of the 431 * destination array. 432 * <p> 433 * If <code>dest</code> is <code>null</code>, then a 434 * <code>NullPointerException</code> is thrown. 435 * <p> 436 * If <code>src</code> is <code>null</code>, then a 437 * <code>NullPointerException</code> is thrown and the destination 438 * array is not modified. 439 * <p> 440 * Otherwise, if any of the following is true, an 441 * <code>ArrayStoreException</code> is thrown and the destination is 442 * not modified: 443 * <ul> 444 * <li>The <code>src</code> argument refers to an object that is not an 445 * array. 446 * <li>The <code>dest</code> argument refers to an object that is not an 447 * array. 448 * <li>The <code>src</code> argument and <code>dest</code> argument refer 449 * to arrays whose component types are different primitive types. 450 * <li>The <code>src</code> argument refers to an array with a primitive 451 * component type and the <code>dest</code> argument refers to an array 452 * with a reference component type. 453 * <li>The <code>src</code> argument refers to an array with a reference 454 * component type and the <code>dest</code> argument refers to an array 455 * with a primitive component type. 456 * </ul> 457 * <p> 458 * Otherwise, if any of the following is true, an 459 * <code>IndexOutOfBoundsException</code> is 460 * thrown and the destination is not modified: 461 * <ul> 462 * <li>The <code>srcPos</code> argument is negative. 463 * <li>The <code>destPos</code> argument is negative. 464 * <li>The <code>length</code> argument is negative. 465 * <li><code>srcPos+length</code> is greater than 466 * <code>src.length</code>, the length of the source array. 467 * <li><code>destPos+length</code> is greater than 468 * <code>dest.length</code>, the length of the destination array. 469 * </ul> 470 * <p> 471 * Otherwise, if any actual component of the source array from 472 * position <code>srcPos</code> through 473 * <code>srcPos+length-1</code> cannot be converted to the component 474 * type of the destination array by assignment conversion, an 475 * <code>ArrayStoreException</code> is thrown. In this case, let 476 * <b><i>k</i></b> be the smallest nonnegative integer less than 477 * length such that <code>src[srcPos+</code><i>k</i><code>]</code> 478 * cannot be converted to the component type of the destination 479 * array; when the exception is thrown, source array components from 480 * positions <code>srcPos</code> through 481 * <code>srcPos+</code><i>k</i><code>-1</code> 482 * will already have been copied to destination array positions 483 * <code>destPos</code> through 484 * <code>destPos+</code><i>k</I><code>-1</code> and no other 485 * positions of the destination array will have been modified. 486 * (Because of the restrictions already itemized, this 487 * paragraph effectively applies only to the situation where both 488 * arrays have component types that are reference types.) 489 * 490 * @param src the source array. 491 * @param srcPos starting position in the source array. 492 * @param dest the destination array. 493 * @param destPos starting position in the destination data. 494 * @param length the number of array elements to be copied. 495 * @exception IndexOutOfBoundsException if copying would cause 496 * access of data outside array bounds. 497 * @exception ArrayStoreException if an element in the <code>src</code> 498 * array could not be stored into the <code>dest</code> array 499 * because of a type mismatch. 500 * @exception NullPointerException if either <code>src</code> or 501 * <code>dest</code> is <code>null</code>. 502 */ 503 @HotSpotIntrinsicCandidate 504 public static native void arraycopy(Object src, int srcPos, 505 Object dest, int destPos, 506 int length); 507 508 /** 509 * Returns the same hash code for the given object as 510 * would be returned by the default method hashCode(), 511 * whether or not the given object's class overrides 512 * hashCode(). 513 * The hash code for the null reference is zero. 514 * 515 * @param x object for which the hashCode is to be calculated 516 * @return the hashCode 517 * @since 1.1 518 */ 519 @HotSpotIntrinsicCandidate 520 public static native int identityHashCode(Object x); 521 522 /** 523 * System properties. The following properties are guaranteed to be defined: 524 * <dl> 525 * <dt>java.version <dd>Java version number 526 * <dt>java.vendor <dd>Java vendor specific string 527 * <dt>java.vendor.url <dd>Java vendor URL 528 * <dt>java.home <dd>Java installation directory 529 * <dt>java.class.version <dd>Java class version number 530 * <dt>java.class.path <dd>Java classpath 531 * <dt>os.name <dd>Operating System Name 532 * <dt>os.arch <dd>Operating System Architecture 533 * <dt>os.version <dd>Operating System Version 534 * <dt>file.separator <dd>File separator ("/" on Unix) 535 * <dt>path.separator <dd>Path separator (":" on Unix) 536 * <dt>line.separator <dd>Line separator ("\n" on Unix) 537 * <dt>user.name <dd>User account name 538 * <dt>user.home <dd>User home directory 539 * <dt>user.dir <dd>User's current working directory 540 * </dl> 541 */ 542 543 private static Properties props; 544 private static native Properties initProperties(Properties props); 545 546 /** 547 * Determines the current system properties. 548 * <p> 549 * First, if there is a security manager, its 550 * <code>checkPropertiesAccess</code> method is called with no 551 * arguments. This may result in a security exception. 552 * <p> 553 * The current set of system properties for use by the 554 * {@link #getProperty(String)} method is returned as a 555 * <code>Properties</code> object. If there is no current set of 556 * system properties, a set of system properties is first created and 557 * initialized. This set of system properties always includes values 558 * for the following keys: 559 * <table summary="Shows property keys and associated values"> 560 * <tr><th>Key</th> 561 * <th>Description of Associated Value</th></tr> 562 * <tr><td><code>java.version</code></td> 563 * <td>Java Runtime Environment version</td></tr> 564 * <tr><td><code>java.vendor</code></td> 565 * <td>Java Runtime Environment vendor</td></tr> 566 * <tr><td><code>java.vendor.url</code></td> 567 * <td>Java vendor URL</td></tr> 568 * <tr><td><code>java.home</code></td> 569 * <td>Java installation directory</td></tr> 570 * <tr><td><code>java.vm.specification.version</code></td> 571 * <td>Java Virtual Machine specification version</td></tr> 572 * <tr><td><code>java.vm.specification.vendor</code></td> 573 * <td>Java Virtual Machine specification vendor</td></tr> 574 * <tr><td><code>java.vm.specification.name</code></td> 575 * <td>Java Virtual Machine specification name</td></tr> 576 * <tr><td><code>java.vm.version</code></td> 577 * <td>Java Virtual Machine implementation version</td></tr> 578 * <tr><td><code>java.vm.vendor</code></td> 579 * <td>Java Virtual Machine implementation vendor</td></tr> 580 * <tr><td><code>java.vm.name</code></td> 581 * <td>Java Virtual Machine implementation name</td></tr> 582 * <tr><td><code>java.specification.version</code></td> 583 * <td>Java Runtime Environment specification version</td></tr> 584 * <tr><td><code>java.specification.vendor</code></td> 585 * <td>Java Runtime Environment specification vendor</td></tr> 586 * <tr><td><code>java.specification.name</code></td> 587 * <td>Java Runtime Environment specification name</td></tr> 588 * <tr><td><code>java.class.version</code></td> 589 * <td>Java class format version number</td></tr> 590 * <tr><td><code>java.class.path</code></td> 591 * <td>Java class path</td></tr> 592 * <tr><td><code>java.library.path</code></td> 593 * <td>List of paths to search when loading libraries</td></tr> 594 * <tr><td><code>java.io.tmpdir</code></td> 595 * <td>Default temp file path</td></tr> 596 * <tr><td><code>java.compiler</code></td> 597 * <td>Name of JIT compiler to use</td></tr> 598 * <tr><td><code>os.name</code></td> 599 * <td>Operating system name</td></tr> 600 * <tr><td><code>os.arch</code></td> 601 * <td>Operating system architecture</td></tr> 602 * <tr><td><code>os.version</code></td> 603 * <td>Operating system version</td></tr> 604 * <tr><td><code>file.separator</code></td> 605 * <td>File separator ("/" on UNIX)</td></tr> 606 * <tr><td><code>path.separator</code></td> 607 * <td>Path separator (":" on UNIX)</td></tr> 608 * <tr><td><code>line.separator</code></td> 609 * <td>Line separator ("\n" on UNIX)</td></tr> 610 * <tr><td><code>user.name</code></td> 611 * <td>User's account name</td></tr> 612 * <tr><td><code>user.home</code></td> 613 * <td>User's home directory</td></tr> 614 * <tr><td><code>user.dir</code></td> 615 * <td>User's current working directory</td></tr> 616 * </table> 617 * <p> 618 * Multiple paths in a system property value are separated by the path 619 * separator character of the platform. 620 * <p> 621 * Note that even if the security manager does not permit the 622 * <code>getProperties</code> operation, it may choose to permit the 623 * {@link #getProperty(String)} operation. 624 * 625 * @return the system properties 626 * @exception SecurityException if a security manager exists and its 627 * <code>checkPropertiesAccess</code> method doesn't allow access 628 * to the system properties. 629 * @see #setProperties 630 * @see java.lang.SecurityException 631 * @see java.lang.SecurityManager#checkPropertiesAccess() 632 * @see java.util.Properties 633 */ 634 public static Properties getProperties() { 635 SecurityManager sm = getSecurityManager(); 636 if (sm != null) { 637 sm.checkPropertiesAccess(); 638 } 639 640 return props; 641 } 642 643 /** 644 * Returns the system-dependent line separator string. It always 645 * returns the same value - the initial value of the {@linkplain 646 * #getProperty(String) system property} {@code line.separator}. 647 * 648 * <p>On UNIX systems, it returns {@code "\n"}; on Microsoft 649 * Windows systems it returns {@code "\r\n"}. 650 * 651 * @return the system-dependent line separator string 652 * @since 1.7 653 */ 654 public static String lineSeparator() { 655 return lineSeparator; 656 } 657 658 private static String lineSeparator; 659 660 /** 661 * Sets the system properties to the <code>Properties</code> 662 * argument. 663 * <p> 664 * First, if there is a security manager, its 665 * <code>checkPropertiesAccess</code> method is called with no 666 * arguments. This may result in a security exception. 667 * <p> 668 * The argument becomes the current set of system properties for use 669 * by the {@link #getProperty(String)} method. If the argument is 670 * <code>null</code>, then the current set of system properties is 671 * forgotten. 672 * 673 * @param props the new system properties. 674 * @exception SecurityException if a security manager exists and its 675 * <code>checkPropertiesAccess</code> method doesn't allow access 676 * to the system properties. 677 * @see #getProperties 678 * @see java.util.Properties 679 * @see java.lang.SecurityException 680 * @see java.lang.SecurityManager#checkPropertiesAccess() 681 */ 682 public static void setProperties(Properties props) { 683 SecurityManager sm = getSecurityManager(); 684 if (sm != null) { 685 sm.checkPropertiesAccess(); 686 } 687 if (props == null) { 688 props = new Properties(); 689 initProperties(props); 690 } 691 System.props = props; 692 } 693 694 /** 695 * Gets the system property indicated by the specified key. 696 * <p> 697 * First, if there is a security manager, its 698 * <code>checkPropertyAccess</code> method is called with the key as 699 * its argument. This may result in a SecurityException. 700 * <p> 701 * If there is no current set of system properties, a set of system 702 * properties is first created and initialized in the same manner as 703 * for the <code>getProperties</code> method. 704 * 705 * @param key the name of the system property. 706 * @return the string value of the system property, 707 * or <code>null</code> if there is no property with that key. 708 * 709 * @exception SecurityException if a security manager exists and its 710 * <code>checkPropertyAccess</code> method doesn't allow 711 * access to the specified system property. 712 * @exception NullPointerException if <code>key</code> is 713 * <code>null</code>. 714 * @exception IllegalArgumentException if <code>key</code> is empty. 715 * @see #setProperty 716 * @see java.lang.SecurityException 717 * @see java.lang.SecurityManager#checkPropertyAccess(java.lang.String) 718 * @see java.lang.System#getProperties() 719 */ 720 public static String getProperty(String key) { 721 checkKey(key); 722 SecurityManager sm = getSecurityManager(); 723 if (sm != null) { 724 sm.checkPropertyAccess(key); 725 } 726 727 return props.getProperty(key); 728 } 729 730 /** 731 * Gets the system property indicated by the specified key. 732 * <p> 733 * First, if there is a security manager, its 734 * <code>checkPropertyAccess</code> method is called with the 735 * <code>key</code> as its argument. 736 * <p> 737 * If there is no current set of system properties, a set of system 738 * properties is first created and initialized in the same manner as 739 * for the <code>getProperties</code> method. 740 * 741 * @param key the name of the system property. 742 * @param def a default value. 743 * @return the string value of the system property, 744 * or the default value if there is no property with that key. 745 * 746 * @exception SecurityException if a security manager exists and its 747 * <code>checkPropertyAccess</code> method doesn't allow 748 * access to the specified system property. 749 * @exception NullPointerException if <code>key</code> is 750 * <code>null</code>. 751 * @exception IllegalArgumentException if <code>key</code> is empty. 752 * @see #setProperty 753 * @see java.lang.SecurityManager#checkPropertyAccess(java.lang.String) 754 * @see java.lang.System#getProperties() 755 */ 756 public static String getProperty(String key, String def) { 757 checkKey(key); 758 SecurityManager sm = getSecurityManager(); 759 if (sm != null) { 760 sm.checkPropertyAccess(key); 761 } 762 763 return props.getProperty(key, def); 764 } 765 766 /** 767 * Sets the system property indicated by the specified key. 768 * <p> 769 * First, if a security manager exists, its 770 * <code>SecurityManager.checkPermission</code> method 771 * is called with a <code>PropertyPermission(key, "write")</code> 772 * permission. This may result in a SecurityException being thrown. 773 * If no exception is thrown, the specified property is set to the given 774 * value. 775 * 776 * @param key the name of the system property. 777 * @param value the value of the system property. 778 * @return the previous value of the system property, 779 * or <code>null</code> if it did not have one. 780 * 781 * @exception SecurityException if a security manager exists and its 782 * <code>checkPermission</code> method doesn't allow 783 * setting of the specified property. 784 * @exception NullPointerException if <code>key</code> or 785 * <code>value</code> is <code>null</code>. 786 * @exception IllegalArgumentException if <code>key</code> is empty. 787 * @see #getProperty 788 * @see java.lang.System#getProperty(java.lang.String) 789 * @see java.lang.System#getProperty(java.lang.String, java.lang.String) 790 * @see java.util.PropertyPermission 791 * @see SecurityManager#checkPermission 792 * @since 1.2 793 */ 794 public static String setProperty(String key, String value) { 795 checkKey(key); 796 SecurityManager sm = getSecurityManager(); 797 if (sm != null) { 798 sm.checkPermission(new PropertyPermission(key, 799 SecurityConstants.PROPERTY_WRITE_ACTION)); 800 } 801 802 return (String) props.setProperty(key, value); 803 } 804 805 /** 806 * Removes the system property indicated by the specified key. 807 * <p> 808 * First, if a security manager exists, its 809 * <code>SecurityManager.checkPermission</code> method 810 * is called with a <code>PropertyPermission(key, "write")</code> 811 * permission. This may result in a SecurityException being thrown. 812 * If no exception is thrown, the specified property is removed. 813 * 814 * @param key the name of the system property to be removed. 815 * @return the previous string value of the system property, 816 * or <code>null</code> if there was no property with that key. 817 * 818 * @exception SecurityException if a security manager exists and its 819 * <code>checkPropertyAccess</code> method doesn't allow 820 * access to the specified system property. 821 * @exception NullPointerException if <code>key</code> is 822 * <code>null</code>. 823 * @exception IllegalArgumentException if <code>key</code> is empty. 824 * @see #getProperty 825 * @see #setProperty 826 * @see java.util.Properties 827 * @see java.lang.SecurityException 828 * @see java.lang.SecurityManager#checkPropertiesAccess() 829 * @since 1.5 830 */ 831 public static String clearProperty(String key) { 832 checkKey(key); 833 SecurityManager sm = getSecurityManager(); 834 if (sm != null) { 835 sm.checkPermission(new PropertyPermission(key, "write")); 836 } 837 838 return (String) props.remove(key); 839 } 840 841 private static void checkKey(String key) { 842 if (key == null) { 843 throw new NullPointerException("key can't be null"); 844 } 845 if (key.equals("")) { 846 throw new IllegalArgumentException("key can't be empty"); 847 } 848 } 849 850 /** 851 * Gets the value of the specified environment variable. An 852 * environment variable is a system-dependent external named 853 * value. 854 * 855 * <p>If a security manager exists, its 856 * {@link SecurityManager#checkPermission checkPermission} 857 * method is called with a 858 * <code>{@link RuntimePermission}("getenv."+name)</code> 859 * permission. This may result in a {@link SecurityException} 860 * being thrown. If no exception is thrown the value of the 861 * variable <code>name</code> is returned. 862 * 863 * <p><a name="EnvironmentVSSystemProperties"><i>System 864 * properties</i> and <i>environment variables</i></a> are both 865 * conceptually mappings between names and values. Both 866 * mechanisms can be used to pass user-defined information to a 867 * Java process. Environment variables have a more global effect, 868 * because they are visible to all descendants of the process 869 * which defines them, not just the immediate Java subprocess. 870 * They can have subtly different semantics, such as case 871 * insensitivity, on different operating systems. For these 872 * reasons, environment variables are more likely to have 873 * unintended side effects. It is best to use system properties 874 * where possible. Environment variables should be used when a 875 * global effect is desired, or when an external system interface 876 * requires an environment variable (such as <code>PATH</code>). 877 * 878 * <p>On UNIX systems the alphabetic case of <code>name</code> is 879 * typically significant, while on Microsoft Windows systems it is 880 * typically not. For example, the expression 881 * <code>System.getenv("FOO").equals(System.getenv("foo"))</code> 882 * is likely to be true on Microsoft Windows. 883 * 884 * @param name the name of the environment variable 885 * @return the string value of the variable, or <code>null</code> 886 * if the variable is not defined in the system environment 887 * @throws NullPointerException if <code>name</code> is <code>null</code> 888 * @throws SecurityException 889 * if a security manager exists and its 890 * {@link SecurityManager#checkPermission checkPermission} 891 * method doesn't allow access to the environment variable 892 * <code>name</code> 893 * @see #getenv() 894 * @see ProcessBuilder#environment() 895 */ 896 public static String getenv(String name) { 897 SecurityManager sm = getSecurityManager(); 898 if (sm != null) { 899 sm.checkPermission(new RuntimePermission("getenv."+name)); 900 } 901 902 return ProcessEnvironment.getenv(name); 903 } 904 905 906 /** 907 * Returns an unmodifiable string map view of the current system environment. 908 * The environment is a system-dependent mapping from names to 909 * values which is passed from parent to child processes. 910 * 911 * <p>If the system does not support environment variables, an 912 * empty map is returned. 913 * 914 * <p>The returned map will never contain null keys or values. 915 * Attempting to query the presence of a null key or value will 916 * throw a {@link NullPointerException}. Attempting to query 917 * the presence of a key or value which is not of type 918 * {@link String} will throw a {@link ClassCastException}. 919 * 920 * <p>The returned map and its collection views may not obey the 921 * general contract of the {@link Object#equals} and 922 * {@link Object#hashCode} methods. 923 * 924 * <p>The returned map is typically case-sensitive on all platforms. 925 * 926 * <p>If a security manager exists, its 927 * {@link SecurityManager#checkPermission checkPermission} 928 * method is called with a 929 * <code>{@link RuntimePermission}("getenv.*")</code> 930 * permission. This may result in a {@link SecurityException} being 931 * thrown. 932 * 933 * <p>When passing information to a Java subprocess, 934 * <a href=#EnvironmentVSSystemProperties>system properties</a> 935 * are generally preferred over environment variables. 936 * 937 * @return the environment as a map of variable names to values 938 * @throws SecurityException 939 * if a security manager exists and its 940 * {@link SecurityManager#checkPermission checkPermission} 941 * method doesn't allow access to the process environment 942 * @see #getenv(String) 943 * @see ProcessBuilder#environment() 944 * @since 1.5 945 */ 946 public static java.util.Map<String,String> getenv() { 947 SecurityManager sm = getSecurityManager(); 948 if (sm != null) { 949 sm.checkPermission(new RuntimePermission("getenv.*")); 950 } 951 952 return ProcessEnvironment.getenv(); 953 } 954 955 /** 956 * The minimum set of methods that a logger returned by the 957 * {@link LoggerFinder} service should implement. 958 * Instances of loggers implementing this interface are obtained from 959 * the {@link java.lang.System System} class, by calling 960 * {@link java.lang.System#getLogger(java.lang.String) System.getLogger(loggerName)} 961 * or {@link java.lang.System#getLogger(java.lang.String, java.util.ResourceBundle) 962 * System.getLogger(loggerName, bundle)}. 963 * <p> 964 * Unless 965 * 966 * @see java.lang.System 967 * @see java.lang.System.LoggerFinder 968 * 969 * @since 9 970 * 971 */ 972 public interface Logger { 973 974 /** 975 * Message levels for the {@link Logger loggers} 976 * returned by the {@link LoggerFinder} service. 977 * <p> 978 * A level has a {@linkplain #getName() name} and {@linkplain 979 * #getSeverity() severity}. 980 * Standard level values are {@link #ALL}, {@link #TRACE}, {@link #DEBUG}, 981 * {@link #INFO}, {@link #WARNING}, {@link #ERROR}, {@link #OFF}, 982 * by order of increasing severity. 983 * <br> 984 * {@link #ALL} and {@link #OFF} 985 * are simple markers with severities mapped respectively to 986 * {@link java.lang.Integer#MIN_VALUE Integer.MIN_VALUE} and 987 * {@link java.lang.Integer#MAX_VALUE Integer.MAX_VALUE}. 988 * <br> 989 * For convenience the severity values are mapped to corresponding 990 * {@link java.util.logging.Level java.util.logging.Level} severity 991 * values. 992 * 993 * @since 9 994 * 995 * @see java.lang.System.LoggerFinder 996 * @see java.lang.System.Logger 997 */ 998 public enum Level { 999 1000 // for convenience, we're reusing java.util.logging.Level int values 1001 // the mapping logic in sun.util.logging.PlatformLogger depends 1002 // on this. 1003 /** 1004 * A marker to indicate that all levels are enabled. 1005 * This level {@linkplain #getSeverity() severity} is 1006 * {@link Integer#MIN_VALUE}. 1007 */ 1008 ALL(Integer.MIN_VALUE), // usually mapped to/from j.u.l.Level.ALL 1009 /** 1010 * {@code TRACE} level: usually used to log diagnostic information. 1011 * This level {@linkplain #getSeverity() severity} is 1012 * {@code 400}. 1013 */ 1014 TRACE(400), // usually mapped to/from j.u.l.Level.FINER 1015 /** 1016 * {@code DEBUG} level: usually used to log debug information traces. 1017 * This level {@linkplain #getSeverity() severity} is 1018 * {@code 500}. 1019 */ 1020 DEBUG(500), // usually mapped to/from j.u.l.Level.FINEST/FINE/CONFIG 1021 /** 1022 * {@code INFO} level: usually used to log information messages. 1023 * This level {@linkplain #getSeverity() severity} is 1024 * {@code 800}. 1025 */ 1026 INFO(800), // usually mapped to/from j.u.l.Level.INFO 1027 /** 1028 * {@code WARNING} level: usually used to log warning messages. 1029 * This level {@linkplain #getSeverity() severity} is 1030 * {@code 900}. 1031 */ 1032 WARNING(900), // usually mapped to/from j.u.l.Level.WARNING 1033 /** 1034 * {@code ERROR} level: usually used to log error messages. 1035 * This level {@linkplain #getSeverity() severity} is 1036 * {@code 1000}. 1037 */ 1038 ERROR(1000), // usually mapped to/from j.u.l.Level.SEVERE 1039 /** 1040 * A marker to indicate that all levels are disabled. 1041 * This level {@linkplain #getSeverity() severity} is 1042 * {@link Integer#MAX_VALUE}. 1043 */ 1044 OFF(Integer.MAX_VALUE); // usually mapped to/from j.u.l.Level.OFF 1045 1046 private final int severity; 1047 1048 private Level(int severity) { 1049 this.severity = severity; 1050 } 1051 1052 /** 1053 * Returns the name of this level. 1054 * @return this level {@linkplain #name()}. 1055 */ 1056 public final String getName() { 1057 return name(); 1058 } 1059 1060 /** 1061 * Returns the severity of this level. 1062 * A higher severity means a more severe condition. 1063 * @return this level severity. 1064 */ 1065 public final int getSeverity() { 1066 return severity; 1067 } 1068 } 1069 1070 /** 1071 * Returns the name of this logger. 1072 * 1073 * @return the logger name. 1074 */ 1075 public String getName(); 1076 1077 /** 1078 * Checks if a message of the given level would be logged by 1079 * this logger. 1080 * 1081 * @param level the message level. 1082 * @return {@code true} if the given message level is currently being logged. 1083 * 1084 * @throws NullPointerException if {@code level} is {@code null}. 1085 */ 1086 public boolean isLoggable(Level level); 1087 1088 /** 1089 * Logs a message. 1090 * 1091 * @implSpec The default implementation for this method calls 1092 * {@code this.log(level, (ResourceBundle)null, msg, (Object[])null);} 1093 * 1094 * @param level the message level. 1095 * @param msg the string message (or a key in the message catalog, if 1096 * this logger is a {@link 1097 * LoggerFinder#getLocalizedLogger(java.lang.String, java.util.ResourceBundle, java.lang.Class) 1098 * localized logger}). 1099 * 1100 * @throws NullPointerException if {@code level} is {@code null}. 1101 */ 1102 public default void log(Level level, String msg) { 1103 log(level, (ResourceBundle) null, msg, (Object[]) null); 1104 } 1105 1106 /** 1107 * Logs a lazily supplied message. 1108 * <p> 1109 * If the logger is currently enabled for the given message level 1110 * then a message is logged that is the result produced by the 1111 * given supplier function. Otherwise, the supplier is not operated on. 1112 * 1113 * @implSpec When logging is enabled for the given level, the default 1114 * implementation for this method calls 1115 * {@code this.log(level, (ResourceBundle)null, msgSupplier.get(), (Object[])null);} 1116 * 1117 * @param level the message level. 1118 * @param msgSupplier a supplier function that produces a message. 1119 * 1120 * @throws NullPointerException if {@code level} is {@code null}, or if the level 1121 * is loggable and {@code msgSupplier} is {@code null}. 1122 */ 1123 public default void log(Level level, Supplier<String> msgSupplier) { 1124 if (isLoggable(level)) { 1125 log(level, (ResourceBundle) null, msgSupplier.get(), (Object[]) null); 1126 } 1127 } 1128 1129 /** 1130 * Logs a message produced from the given object. 1131 * <p> 1132 * If the logger is currently enabled for the given message level then 1133 * a message is logged that, by default, is the result produced from 1134 * calling toString on the given object. 1135 * Otherwise, the object is not operated on. 1136 * 1137 * @implSpec When logging is enabled for the given level, the default 1138 * implementation for this method calls 1139 * {@code this.log(level, (ResourceBundle)null, obj.toString(), (Object[])null);} 1140 * 1141 * @param level the message level. 1142 * @param obj the object to log. 1143 * 1144 * @throws NullPointerException if {@code level} is {@code null}, or if the level 1145 * is loggable and {@code obj} is {@code null}. 1146 */ 1147 public default void log(Level level, Object obj) { 1148 if (isLoggable(level)) { 1149 this.log(level, (ResourceBundle) null, obj.toString(), (Object[]) null); 1150 } 1151 } 1152 1153 /** 1154 * Logs a message associated with a given throwable. 1155 * 1156 * @implSpec The default implementation for this method calls 1157 * {@code this.log(level, (ResourceBundle)null, msg, thrown);} 1158 * 1159 * @param level the message level. 1160 * @param msg the string message (or a key in the message catalog, if 1161 * this logger is a {@link 1162 * LoggerFinder#getLocalizedLogger(java.lang.String, java.util.ResourceBundle, java.lang.Class) 1163 * localized logger}). 1164 * @param thrown a {@code Throwable} associated with the log message. 1165 * 1166 * @throws NullPointerException if {@code level} is {@code null}. 1167 */ 1168 public default void log(Level level, String msg, Throwable thrown) { 1169 this.log(level, null, msg, thrown); 1170 } 1171 1172 /** 1173 * Logs a lazily supplied message associated with a given throwable. 1174 * <p> 1175 * If the logger is currently enabled for the given message level 1176 * then a message is logged that is the result produced by the 1177 * given supplier function. Otherwise, the supplier is not operated on. 1178 * 1179 * @implSpec When logging is enabled for the given level, the default 1180 * implementation for this method calls 1181 * {@code this.log(level, (ResourceBundle)null, msgSupplier.get(), thrown);} 1182 * 1183 * @param level one of the message level identifiers. 1184 * @param msgSupplier a supplier function that produces a message. 1185 * @param thrown a {@code Throwable} associated with log message. 1186 * 1187 * @throws NullPointerException if {@code level} is {@code null}, or if the level 1188 * is loggable and {@code msgSupplier} is {@code null}. 1189 */ 1190 public default void log(Level level, Supplier<String> msgSupplier, 1191 Throwable thrown) { 1192 if (isLoggable(level)) { 1193 this.log(level, null, msgSupplier.get(), thrown); 1194 } 1195 } 1196 1197 /** 1198 * Logs a message with an optional list of parameters. 1199 * 1200 * @implSpec The default implementation for this method calls 1201 * {@code this.log(level, (ResourceBundle)null, format, params);} 1202 * 1203 * @param level one of the message level identifiers. 1204 * @param format the string message format (or a key in the message 1205 * catalog, if this logger is a {@link 1206 * LoggerFinder#getLocalizedLogger(java.lang.String, java.util.ResourceBundle, java.lang.Class) 1207 * localized logger}). 1208 * @param params an optional list of parameters to the message (may be 1209 * none). 1210 * 1211 * @throws NullPointerException if {@code level} is {@code null}. 1212 */ 1213 public default void log(Level level, String format, Object... params) { 1214 this.log(level, null, format, params); 1215 } 1216 1217 /** 1218 * Logs a localized message associated with a given throwable. 1219 * <p> 1220 * If the given resource bundle is non-{@code null}, the {@code msg} 1221 * string is localized using the given resource bundle. 1222 * Otherwise the {@code msg} string is not localized. 1223 * 1224 * @param level the message level. 1225 * @param bundle a resource bundle to localize {@code msg}, can be 1226 * {@code null}. 1227 * @param msg the string message (or a key in the message catalog, 1228 * if {@code bundle} is not {@code null}). 1229 * @param thrown a {@code Throwable} associated with the log message. 1230 * 1231 * @throws NullPointerException if {@code level} is {@code null}. 1232 */ 1233 public void log(Level level, ResourceBundle bundle, String msg, 1234 Throwable thrown); 1235 1236 /** 1237 * Logs a message with resource bundle and an optional list of 1238 * parameters. 1239 * <p> 1240 * If the given resource bundle is non-{@code null}, the {@code format} 1241 * string is localized using the given resource bundle. 1242 * Otherwise the {@code format} string is not localized. 1243 * 1244 * @param level the message level. 1245 * @param bundle a resource bundle to localize {@code format}, can be 1246 * {@code null}. 1247 * @param format the string message format (or a key in the message 1248 * catalog if {@code bundle} is not {@code null}). 1249 * @param params an optional list of parameters to the message (may be 1250 * none). 1251 * 1252 * @throws NullPointerException if {@code level} is {@code null}. 1253 */ 1254 public void log(Level level, ResourceBundle bundle, String format, 1255 Object... params); 1256 1257 1258 } 1259 1260 /** 1261 * The {@code LoggerFinder} service makes it possible to provide an 1262 * alternate implementation for System.Loggers used in the JDK. 1263 * <p> 1264 * <b>Working with loggers obtained from the {@code LoggerFinder}</b> 1265 * <p> 1266 * The {@code LoggerFinder} class makes it possible to replace 1267 * the logging backend through which logging events originating from 1268 * platform classes will be routed. The backend of the default 1269 * {@code LoggerFinder} implementation is still 1270 * {@code java.util.logging}, but it can now be replaced by providing and 1271 * declaring an alternate implementation of the {@code LoggerFinder} 1272 * service. 1273 * <p> 1274 * The JDK uses the {@link java.util.ServiceLoader} 1275 * facility to locate and load a concrete implementation of the 1276 * {@code LoggerFinder} service, from the {@linkplain 1277 * java.lang.ClassLoader#getSystemClassLoader() System ClassLoader}. 1278 * If no custom implementation is found the JDK will use its own default 1279 * implementation. If more than one implementation is found, a 1280 * {@link java.util.ServiceConfigurationError} will be thrown. 1281 * <p> 1282 * Only one instance of the {@code LoggerFinder} implementation is created. 1283 * That instance is responsible for creating, managing, and configuring 1284 * loggers as appropriate to the underlying framework it is using. 1285 * <p> 1286 * In the JDK, a platform class that needs to log messages will obtain 1287 * a logger that will route messages to a {@link Logger Logger} instance 1288 * obtained from one of the factory methods provided by the 1289 * {@code LoggerFinder} implementation. 1290 * <p> 1291 * {@link Logger Logger} instances obtained from the {@code 1292 * LoggerFinder} factory methods are not directly configurable by 1293 * the application. Configuration is the responsibility of the underlying 1294 * logging backend, and usually requires using APIs specific to that 1295 * backend. 1296 * <p> 1297 * System loggers (loggers obtained on behalf of platform classes) are 1298 * usually kept in a global logger tree which is separated from the 1299 * application logger tree. It is the responsibility of the provider of 1300 * the concrete {@code LoggerFinder} implementation to ensure that 1301 * system loggers can not be configured by an application without proper 1302 * permission checks, as configuration performed on system loggers usually 1303 * affects all applications in the same Java Runtime. 1304 * <p> 1305 * <b>Default Implementation</b> 1306 * <p> 1307 * The JDK default implementation of the {@code LoggerFinder} service 1308 * will attempt to bind to the {@linkplain java.util.logging java.logging} 1309 * module. 1310 * When the {@linkplain java.util.logging java.logging} module is present, 1311 * the default implementation will return {@link Logger} instances wrapping 1312 * instances of {@link java.util.logging.Logger java.util.logging.Logger}. 1313 * In that case, configuration may be performed by direct access to the 1314 * {@code java.util.logging} APIs, using {@link java.util.logging.Logger 1315 * java.util.logging.Logger} and {@link java.util.logging.LogManager} to 1316 * access and configure the backend loggers. 1317 * <br> 1318 * If the {@link java.util.logging java.logging} module is not linked 1319 * with the application, and no service implementation for the 1320 * {@code LoggerFinder} has been found, then the default implementation 1321 * will return a simple logger that prints out all log messages of 1322 * {@link java.lang.System.Logger.Level#INFO INFO} 1323 * level and above to the console ({@code System.err}). 1324 * <br> 1325 * These simple loggers are not configurable. 1326 * <p> 1327 * Note that if an implementation of the {@code LoggerFinder} service 1328 * interface has been found by the {@link java.util.ServiceLoader}, then 1329 * the JDK default implementation of {@code LoggerFinder} is not used and 1330 * configuration can only be performed through APIs provided by the backend 1331 * framework which the custom implementation of {@code LoggerFinder} has 1332 * plugged in. 1333 * <br> 1334 * Libraries and classes that only need loggers to produce log messages 1335 * should therefore not attempt to configure loggers by themselves, as that 1336 * would make them dependant from a specific implementation of the 1337 * {@code LoggerFinder} service. 1338 * <p> 1339 * Note also that the {@linkplain java.util.logging java.logging} module 1340 * does not directly provide an implementation of the {@code LoggerFinder} 1341 * service. The JDK default concrete implementation of {@code LoggerFinder} 1342 * use instead a JDK private API to bind to {@code java.util.logging}. 1343 * This makes it possible for an application to replace the logging backend 1344 * <i>even when the java.logging module is present</i>, by simply providing 1345 * and declaring an implementation of the {@link LoggerFinder} service. 1346 * <p> 1347 * <b>Message Levels and Mapping to {@code java.util.logging}</b> 1348 * <p> 1349 * The {@link Logger.Level Logger.Level} enum defines 1350 * a set of standard levels: {@link Logger.Level#ALL ALL}, 1351 * {@link Logger.Level#TRACE TRACE}, 1352 * {@link Logger.Level#DEBUG DEBUG}, 1353 * {@link Logger.Level#INFO INFO}, 1354 * {@link Logger.Level#WARNING WARNING}, 1355 * {@link Logger.Level#ERROR ERROR}, 1356 * and {@link Logger.Level#OFF OFF}, by order of increased severity. 1357 * <br> 1358 * {@link Logger.Level#ALL Level.ALL} and {@link Logger.Level#OFF Level.OFF} 1359 * are simple markers with severities mapped respectively to 1360 * {@link java.lang.Integer#MIN_VALUE Integer.MIN_VALUE} and 1361 * {@link java.lang.Integer#MAX_VALUE Integer.MAX_VALUE}. 1362 * <p> 1363 * When the logging backend supports custom levels, how to map System.Logger 1364 * levels to backend levels is the responsibility of the backend. 1365 * <p> 1366 * When {@link java.util.logging} is the backend, System.Logger levels are 1367 * mapped to {@linkplain java.util.logging.Level java.util.logging levels} 1368 * as follows: 1369 * <br><br> 1370 * <table border="1"> 1371 * <caption>System.Logger Level Mapping</caption> 1372 * <tr><td><b>System.Logger Levels</b></td> 1373 * <td>{@link Logger.Level#ALL ALL}</td> 1374 * <td>{@link Logger.Level#TRACE TRACE}</td> 1375 * <td>{@link Logger.Level#DEBUG DEBUG}</td> 1376 * <td>{@link Logger.Level#INFO INFO}</td> 1377 * <td>{@link Logger.Level#WARNING WARNING}</td> 1378 * <td>{@link Logger.Level#ERROR ERROR}</td> 1379 * <td>{@link Logger.Level#OFF OFF}</td> 1380 * </tr> 1381 * <tr><td><b>java.util.logging Backend</b></td> 1382 * <td>{@link java.util.logging.Level#ALL ALL}</td> 1383 * <td>{@link java.util.logging.Level#FINER FINER}</td> 1384 * <td>{@link java.util.logging.Level#FINE FINE}</td> 1385 * <td>{@link java.util.logging.Level#INFO INFO}</td> 1386 * <td>{@link java.util.logging.Level#WARNING WARNING}</td> 1387 * <td>{@link java.util.logging.Level#SEVERE SEVERE}</td> 1388 * <td>{@link java.util.logging.Level#OFF OFF}</td> 1389 * </tr> 1390 * </table> 1391 * <p> 1392 * <b>Migrating From {@code java.util.logging}</b> 1393 * <p> 1394 * Usually - an application that uses a logging framework will log messages 1395 * through a logger facade defined (or supported) by that framework. 1396 * Applications that wish to use an external framework should log 1397 * through the facade associated with that framework. 1398 * <p> 1399 * <b>Changing the {@code LoggerFinder} Implementation</b> 1400 * <p> 1401 * An application wishing to change the implementation of the 1402 * {@code LoggerFinder} is expected to provide a concrete implementation 1403 * of the {@code LoggerFinder} abstract class accessible from the 1404 * {@linkplain java.lang.ClassLoader#getSystemClassLoader() 1405 * System ClassLoader} and registered as a service in such a way that it 1406 * can be located and loaded by the {@link java.util.ServiceLoader}. 1407 * Note that because the loaded instance of {@code LoggerFinder} is 1408 * global, it will be only looked for in the {@linkplain 1409 * java.lang.ClassLoader#getSystemClassLoader() System ClassLoader} (and its 1410 * parents). 1411 * <p> 1412 * 1413 * @see java.lang.System 1414 * @see java.lang.System.Logger 1415 * 1416 * @since 9 1417 */ 1418 public static abstract class LoggerFinder { 1419 /** 1420 * The {@code RuntimePermission("loggerFinder")} is 1421 * necessary to subclass and instantiate the {@code LoggerFinder} class, 1422 * as well as to obtain loggers from an instance of that class. 1423 */ 1424 public static final RuntimePermission LOGGERFINDER_PERMISSION = 1425 new RuntimePermission("loggerFinder"); 1426 1427 /** 1428 * Creates a new instance of {@code LoggerFinder}. 1429 * 1430 * Only one instance will be created. 1431 * 1432 * @implNote It is recommended that subclasses of {@code LoggerFinder} 1433 * do not perform any heavy initialization in their constructor, in 1434 * order to avoid possible risks of deadlock or class loading cycles 1435 * during the instantiation of the provider. 1436 * 1437 * @throws SecurityException if the calling code does not have the 1438 * {@code RuntimePermission("loggerFinder")}. 1439 */ 1440 protected LoggerFinder() { 1441 this(checkPermission()); 1442 } 1443 1444 private LoggerFinder(Void unused) { 1445 // nothing to do. 1446 } 1447 1448 private static Void checkPermission() { 1449 final SecurityManager sm = System.getSecurityManager(); 1450 if (sm != null) { 1451 sm.checkPermission(LOGGERFINDER_PERMISSION); 1452 } 1453 return null; 1454 } 1455 1456 /** 1457 * Returns an instance of {@link Logger Logger} 1458 * suitable for the given caller. 1459 * 1460 * @param name the name of the logger. 1461 * @param caller the class for which the logger is being requested. 1462 * 1463 * @return a {@link Logger logger} suitable for the given caller's 1464 * use. 1465 * @throws SecurityException if the calling code does not have the 1466 * {@code RuntimePermission("loggerFinder")}. 1467 */ 1468 public abstract Logger getLogger(String name, /* Module */ Class<?> caller); 1469 1470 /** 1471 * Returns a localizable instance of {@link Logger Logger} 1472 * suitable for the given caller. 1473 * The returned logger will use the provided resource bundle for 1474 * message localization. 1475 * 1476 * @implSpec By default, this method calls {@link 1477 * #getLogger(java.lang.String, java.lang.Class) 1478 * this.getLogger(name, caller)} to obtain a logger, then wraps that 1479 * logger in a {@link Logger} instance where all methods that do not 1480 * take a {@link ResourceBundle} as parameter are redirected to one 1481 * which does - passing the given {@code bundle} for 1482 * localization. So for instance, a call to {@link 1483 * Logger#log(Level, String) Logger.log(Level.INFO, msg)} 1484 * will end up as a call to {@link 1485 * Logger#log(Level, ResourceBundle, String, Object...) 1486 * Logger.log(Level.INFO, bundle, msg, (Object[])null)} on the wrapped 1487 * logger object. 1488 * Note however that by default, string messages returned by {@link 1489 * java.util.function.Supplier Supplier<String>} will not be 1490 * localized, as it is assumed that such strings are messages which are 1491 * already constructed, rather than keys in a resource bundle. 1492 * <p> 1493 * An implementation of {@code LoggerFinder} is not 1494 * constrained to use the default implementation of this method. In 1495 * particular, if the underlying logging backend provides its own 1496 * mechanism for localizing log messages, then such a 1497 * {@code LoggerFinder} would be free to return a logger 1498 * that makes direct use of the mechanism provided by the backend. 1499 * 1500 * @param name the name of the logger. 1501 * @param bundle a resource bundle. 1502 * @param caller the class for which the logger is being requested. 1503 * @return an instance of {@link Logger Logger} which will use the 1504 * provided resource bundle for message localization. 1505 * 1506 * @throws SecurityException if the calling code does not have the 1507 * {@code RuntimePermission("loggerFinder")}. 1508 */ 1509 public Logger getLocalizedLogger(String name, ResourceBundle bundle, 1510 /* Module */ Class<?> caller) { 1511 return new LocalizedLoggerWrapper<>(getLogger(name, caller), bundle); 1512 } 1513 1514 /** 1515 * Returns the loaded {@link LoggerFinder LoggerFinder} instance. 1516 * @return the loaded {@link LoggerFinder LoggerFinder} instance. 1517 * @throws SecurityException if the calling code does not have the 1518 * {@code RuntimePermission("loggerFinder")}. 1519 */ 1520 public static LoggerFinder getLoggerFinder() { 1521 final SecurityManager sm = System.getSecurityManager(); 1522 if (sm != null) { 1523 sm.checkPermission(LOGGERFINDER_PERMISSION); 1524 } 1525 return LoggerFinderLoader.spi(); 1526 } 1527 1528 /** 1529 * Helper class used to load the {@link LoggerFinder}. 1530 */ 1531 final static class LoggerFinderLoader { 1532 private static volatile LoggerFinder spi; 1533 private static final Object lock = new int[0]; 1534 static final Permission CLASSLOADER_PERMISSION = 1535 SecurityConstants.GET_CLASSLOADER_PERMISSION; 1536 static final Permission READ_PERMISSION = 1537 new FilePermission("<<ALL FILES>>", 1538 SecurityConstants.FILE_READ_ACTION); 1539 1540 // This class is static and cannot be instantiated. 1541 private LoggerFinderLoader() { 1542 throw new InternalError("LoggerFinderLoader cannot be instantiated"); 1543 } 1544 1545 1546 /** 1547 * The DefaultLoggerFinder is used when no {@link 1548 * LoggerFinder} implementation can be found. 1549 * <p> 1550 * By default, when {@link java.util.logging} 1551 * is present, the {@code DefaultLoggerFinder} returns loggers that 1552 * wrap {@link java.util.logging.Logger} created by the internal 1553 * {@link sun.util.logging.internal.JdkLoggingProvider}. 1554 * Backend loggers are obtained by 1555 * calling {@link 1556 * java.util.logging.LogManager#demandLoggerFor(java.lang.String, java.lang.Class)}. 1557 * Backend loggers can be configured by direct 1558 * use of the {@link java.util.logging} APIs. 1559 * <p> 1560 * When {@link java.util.logging} 1561 * is <b>not</b> present, the {@code DefaultLoggerFinder} returns 1562 * {@linkplain sun.util.logger.SimpleConsoleLogger 1563 * simple console loggers}. 1564 * By default, only message of level {@code INFO} and above will be 1565 * printed on the console. 1566 * For compatibility reason system loggers can be configured by 1567 * direct use of the internal {@code PlatformLogger} API. 1568 * For application loggers however, there is no API that would allow 1569 * the application to configure these loggers. 1570 * <p> 1571 * Therefore an application that needs to configure loggers should 1572 * either link with {@link java.util.logging} or install its own 1573 * {@link LoggerFinder} service. 1574 */ 1575 final static class DefaultLoggerFinder extends LoggerFinder { 1576 1577 // Default JdkLoggerProvider used when no JdkLoggerProvider is 1578 // declared as an installed service. 1579 static final class DefaultJdkLoggerProvider extends JdkLoggerProvider { 1580 } 1581 1582 private static JdkLoggerProvider loadJdkLoggerProvider() { 1583 final SecurityManager sm = System.getSecurityManager(); 1584 if (sm != null) { 1585 sm.checkPermission(LOGGERFINDER_PERMISSION); 1586 } 1587 1588 final ServiceLoader<JdkLoggerProvider> loader; 1589 if (sm == null) { 1590 loader = ServiceLoader.loadInstalled(JdkLoggerProvider.class); 1591 } else { 1592 // We use limited do privileged here - the minimum set of 1593 // permissions required to 'see' the META-INF/services resources 1594 // seems to be CLASSLOADER_PERMISSION and READ_PERMISSION. 1595 // Note that do privileged is required because 1596 // otherwise the SecurityManager will prevent the ServiceLoader 1597 // from seeing the installed provider. 1598 loader = AccessController.doPrivileged( 1599 (PrivilegedAction<ServiceLoader<JdkLoggerProvider>>) 1600 () -> ServiceLoader.loadInstalled(JdkLoggerProvider.class), 1601 null, CLASSLOADER_PERMISSION, READ_PERMISSION); 1602 } 1603 JdkLoggerProvider result = null; 1604 try { 1605 if (loader.iterator().hasNext()) { 1606 result = loader.iterator().next(); 1607 } 1608 } catch (Throwable x) { 1609 // should report configuration error. 1610 // use the default. 1611 } 1612 if (result == null) { 1613 result = new DefaultJdkLoggerProvider(); 1614 } 1615 return result; 1616 } 1617 1618 final JdkLoggerProvider jdkLoggerProvider; 1619 1620 private DefaultLoggerFinder() { 1621 this(loadJdkLoggerProvider()); 1622 } 1623 1624 private DefaultLoggerFinder(JdkLoggerProvider jdkLoggerProvider) { 1625 this.jdkLoggerProvider = jdkLoggerProvider; 1626 } 1627 1628 @Override 1629 public Logger getLogger(String name, Class<?> caller) { 1630 final SecurityManager sm = System.getSecurityManager(); 1631 if (sm != null) { 1632 sm.checkPermission(LOGGERFINDER_PERMISSION); 1633 } 1634 return jdkLoggerProvider.getJdkLogger(name, caller); 1635 } 1636 1637 } 1638 1639 // Return the loaded LoggerFinder, or load it if not already loaded. 1640 static LoggerFinder spi() { 1641 if (spi != null) return spi; 1642 synchronized(lock) { 1643 if (spi != null) return spi; 1644 spi = AccessController.doPrivileged( 1645 (PrivilegedAction<LoggerFinder>) LoggerFinderLoader::load, 1646 null, LOGGERFINDER_PERMISSION, CLASSLOADER_PERMISSION, READ_PERMISSION); 1647 } 1648 // Since the LoggerFinder is already loaded - we can stop using 1649 // temporary loggers. 1650 BootstrapLogger.redirectTemporaryLoggers(); 1651 return spi; 1652 } 1653 1654 // Loads the LoggerFinder using ServiceLoader. If no LoggerFinder 1655 // is found returns the default (possibly JUL based) implementation 1656 private static LoggerFinder load() { 1657 LoggerFinder result; 1658 try { 1659 ServiceLoader<LoggerFinder> loader = 1660 ServiceLoader.load(LoggerFinder.class, 1661 ClassLoader.getSystemClassLoader()); 1662 final java.util.Iterator<LoggerFinder> iterator = 1663 loader.iterator(); 1664 if (iterator.hasNext()) { 1665 result = iterator.next(); 1666 if (iterator.hasNext()) { 1667 throw new ServiceConfigurationError( 1668 LoggerFinder.class.getName() 1669 + ": several implementations found"); 1670 } 1671 } else { 1672 result = getDefaultImplementation(); 1673 } 1674 } catch(Error | RuntimeException x) { 1675 //TODO: Use an ErrorManager to log that 1676 spi = getDefaultImplementation(); 1677 throw x; 1678 } 1679 return result; 1680 } 1681 1682 private static LoggerFinder getDefaultImplementation() { 1683 return new DefaultLoggerFinder(); 1684 } 1685 1686 } 1687 } 1688 1689 private static LoggerFinder accessProvider() { 1690 return LoggerFinder.LoggerFinderLoader.spi(); 1691 } 1692 1693 /** 1694 * Returns an instance of {@link Logger Logger} suitable for the caller's 1695 * use. 1696 * 1697 * @implSpec 1698 * Instances returned by this method route messages to loggers 1699 * obtained by calling {@link LoggerFinder#getLogger(java.lang.String, java.lang.Class) 1700 * LoggerFinder.getLogger(name, caller)}. 1701 * 1702 * @apiNote 1703 * Calling this method may delay the creation of the actual logger. 1704 * A common reason for delaying the creation of the actual logger is, 1705 * for instance, if the Java Runtime is not finished booting at the time 1706 * the logger is requested. 1707 * 1708 * @param name the name of the logger. 1709 * @return an instance of {@link Logger} that can be used by the calling 1710 * class. 1711 * @throws NullPointerException if {@code name} is {@code null}. 1712 */ 1713 @CallerSensitive 1714 public static Logger getLogger(String name) { 1715 final Class<?> caller = Reflection.getCallerClass(); 1716 // should we use lazy loggers only for platform loggers - not for all 1717 // system loggers? In other words, should we have a version of 1718 // getSystemLogger that takes an additional 'allowLazyLogger' boolean 1719 // parameter? 1720 // This method will create LazyLogger only if the Caller is in the 1721 // Boot ClassLoader 1722 return LazyLoggers.getLogger(Objects.requireNonNull(name), caller); 1723 } 1724 1725 /** 1726 * Returns a localizable instance of {@link Logger 1727 * Logger} suitable for the caller use. 1728 * The returned logger will use the provided resource bundle for message 1729 * localization. 1730 * 1731 * @implSpec 1732 * The returned logger will perform message localization as specified 1733 * by {@link LoggerFinder#getLocalizedLogger(java.lang.String, 1734 * java.util.ResourceBundle, java.lang.Class) 1735 * LoggerFinder.getLocalizedLogger(name, bundle, caller}. 1736 * 1737 * @apiNote 1738 * Calling this method may trigger the immediate loading and initialization 1739 * of the {@link LoggerFinder} service, which may cause issues if the 1740 * Java Runtime is not ready to initialize the concrete service 1741 * implementation yet. 1742 * Platform classes which may be loaded early in the boot sequence and 1743 * need to log localized messages may prefer to create a logger using 1744 * {@link #getLogger(java.lang.String)} and then use the log methods that 1745 * take a resource bundle as parameter. 1746 * 1747 * @param name the name of the logger. 1748 * @param bundle a resource bundle. 1749 * @return an instance of {@link Logger} which will use the provided 1750 * resource bundle for message localization. 1751 * @throws NullPointerException if {@code name} or {@code bundle} is 1752 * {@code null} 1753 */ 1754 @CallerSensitive 1755 public static Logger getLogger(String name, ResourceBundle bundle) { 1756 final Class<?> caller = Reflection.getCallerClass(); 1757 final SecurityManager sm = System.getSecurityManager(); 1758 final ResourceBundle rb = Objects.requireNonNull(bundle); 1759 // We don't use LazyLoggers if a resource bundle is specified. 1760 // Bootstrap sensitive classes in the JDK do not use resource bundles 1761 // when logging. This could be revisited later, if it needs to. 1762 if (sm != null) { 1763 return AccessController.doPrivileged((PrivilegedAction<Logger>) 1764 () -> accessProvider().getLocalizedLogger(name, rb, caller), 1765 null, 1766 LoggerFinder.LOGGERFINDER_PERMISSION); 1767 } 1768 return accessProvider().getLocalizedLogger(name, rb, caller); 1769 } 1770 1771 /** 1772 * Terminates the currently running Java Virtual Machine. The 1773 * argument serves as a status code; by convention, a nonzero status 1774 * code indicates abnormal termination. 1775 * <p> 1776 * This method calls the <code>exit</code> method in class 1777 * <code>Runtime</code>. This method never returns normally. 1778 * <p> 1779 * The call <code>System.exit(n)</code> is effectively equivalent to 1780 * the call: 1781 * <blockquote><pre> 1782 * Runtime.getRuntime().exit(n) 1783 * </pre></blockquote> 1784 * 1785 * @param status exit status. 1786 * @throws SecurityException 1787 * if a security manager exists and its <code>checkExit</code> 1788 * method doesn't allow exit with the specified status. 1789 * @see java.lang.Runtime#exit(int) 1790 */ 1791 public static void exit(int status) { 1792 Runtime.getRuntime().exit(status); 1793 } 1794 1795 /** 1796 * Runs the garbage collector. 1797 * <p> 1798 * Calling the <code>gc</code> method suggests that the Java Virtual 1799 * Machine expend effort toward recycling unused objects in order to 1800 * make the memory they currently occupy available for quick reuse. 1801 * When control returns from the method call, the Java Virtual 1802 * Machine has made a best effort to reclaim space from all discarded 1803 * objects. 1804 * <p> 1805 * The call <code>System.gc()</code> is effectively equivalent to the 1806 * call: 1807 * <blockquote><pre> 1808 * Runtime.getRuntime().gc() 1809 * </pre></blockquote> 1810 * 1811 * @see java.lang.Runtime#gc() 1812 */ 1813 public static void gc() { 1814 Runtime.getRuntime().gc(); 1815 } 1816 1817 /** 1818 * Runs the finalization methods of any objects pending finalization. 1819 * <p> 1820 * Calling this method suggests that the Java Virtual Machine expend 1821 * effort toward running the <code>finalize</code> methods of objects 1822 * that have been found to be discarded but whose <code>finalize</code> 1823 * methods have not yet been run. When control returns from the 1824 * method call, the Java Virtual Machine has made a best effort to 1825 * complete all outstanding finalizations. 1826 * <p> 1827 * The call <code>System.runFinalization()</code> is effectively 1828 * equivalent to the call: 1829 * <blockquote><pre> 1830 * Runtime.getRuntime().runFinalization() 1831 * </pre></blockquote> 1832 * 1833 * @see java.lang.Runtime#runFinalization() 1834 */ 1835 public static void runFinalization() { 1836 Runtime.getRuntime().runFinalization(); 1837 } 1838 1839 /** 1840 * Enable or disable finalization on exit; doing so specifies that the 1841 * finalizers of all objects that have finalizers that have not yet been 1842 * automatically invoked are to be run before the Java runtime exits. 1843 * By default, finalization on exit is disabled. 1844 * 1845 * <p>If there is a security manager, 1846 * its <code>checkExit</code> method is first called 1847 * with 0 as its argument to ensure the exit is allowed. 1848 * This could result in a SecurityException. 1849 * 1850 * @deprecated This method is inherently unsafe. It may result in 1851 * finalizers being called on live objects while other threads are 1852 * concurrently manipulating those objects, resulting in erratic 1853 * behavior or deadlock. 1854 * @param value indicating enabling or disabling of finalization 1855 * @throws SecurityException 1856 * if a security manager exists and its <code>checkExit</code> 1857 * method doesn't allow the exit. 1858 * 1859 * @see java.lang.Runtime#exit(int) 1860 * @see java.lang.Runtime#gc() 1861 * @see java.lang.SecurityManager#checkExit(int) 1862 * @since 1.1 1863 */ 1864 @Deprecated 1865 public static void runFinalizersOnExit(boolean value) { 1866 Runtime.runFinalizersOnExit(value); 1867 } 1868 1869 /** 1870 * Loads the native library specified by the filename argument. The filename 1871 * argument must be an absolute path name. 1872 * 1873 * If the filename argument, when stripped of any platform-specific library 1874 * prefix, path, and file extension, indicates a library whose name is, 1875 * for example, L, and a native library called L is statically linked 1876 * with the VM, then the JNI_OnLoad_L function exported by the library 1877 * is invoked rather than attempting to load a dynamic library. 1878 * A filename matching the argument does not have to exist in the 1879 * file system. 1880 * See the JNI Specification for more details. 1881 * 1882 * Otherwise, the filename argument is mapped to a native library image in 1883 * an implementation-dependent manner. 1884 * 1885 * <p> 1886 * The call <code>System.load(name)</code> is effectively equivalent 1887 * to the call: 1888 * <blockquote><pre> 1889 * Runtime.getRuntime().load(name) 1890 * </pre></blockquote> 1891 * 1892 * @param filename the file to load. 1893 * @exception SecurityException if a security manager exists and its 1894 * <code>checkLink</code> method doesn't allow 1895 * loading of the specified dynamic library 1896 * @exception UnsatisfiedLinkError if either the filename is not an 1897 * absolute path name, the native library is not statically 1898 * linked with the VM, or the library cannot be mapped to 1899 * a native library image by the host system. 1900 * @exception NullPointerException if <code>filename</code> is 1901 * <code>null</code> 1902 * @see java.lang.Runtime#load(java.lang.String) 1903 * @see java.lang.SecurityManager#checkLink(java.lang.String) 1904 */ 1905 @CallerSensitive 1906 public static void load(String filename) { 1907 Runtime.getRuntime().load0(Reflection.getCallerClass(), filename); 1908 } 1909 1910 /** 1911 * Loads the native library specified by the <code>libname</code> 1912 * argument. The <code>libname</code> argument must not contain any platform 1913 * specific prefix, file extension or path. If a native library 1914 * called <code>libname</code> is statically linked with the VM, then the 1915 * JNI_OnLoad_<code>libname</code> function exported by the library is invoked. 1916 * See the JNI Specification for more details. 1917 * 1918 * Otherwise, the libname argument is loaded from a system library 1919 * location and mapped to a native library image in an implementation- 1920 * dependent manner. 1921 * <p> 1922 * The call <code>System.loadLibrary(name)</code> is effectively 1923 * equivalent to the call 1924 * <blockquote><pre> 1925 * Runtime.getRuntime().loadLibrary(name) 1926 * </pre></blockquote> 1927 * 1928 * @param libname the name of the library. 1929 * @exception SecurityException if a security manager exists and its 1930 * <code>checkLink</code> method doesn't allow 1931 * loading of the specified dynamic library 1932 * @exception UnsatisfiedLinkError if either the libname argument 1933 * contains a file path, the native library is not statically 1934 * linked with the VM, or the library cannot be mapped to a 1935 * native library image by the host system. 1936 * @exception NullPointerException if <code>libname</code> is 1937 * <code>null</code> 1938 * @see java.lang.Runtime#loadLibrary(java.lang.String) 1939 * @see java.lang.SecurityManager#checkLink(java.lang.String) 1940 */ 1941 @CallerSensitive 1942 public static void loadLibrary(String libname) { 1943 Runtime.getRuntime().loadLibrary0(Reflection.getCallerClass(), libname); 1944 } 1945 1946 /** 1947 * Maps a library name into a platform-specific string representing 1948 * a native library. 1949 * 1950 * @param libname the name of the library. 1951 * @return a platform-dependent native library name. 1952 * @exception NullPointerException if <code>libname</code> is 1953 * <code>null</code> 1954 * @see java.lang.System#loadLibrary(java.lang.String) 1955 * @see java.lang.ClassLoader#findLibrary(java.lang.String) 1956 * @since 1.2 1957 */ 1958 public static native String mapLibraryName(String libname); 1959 1960 /** 1961 * Create PrintStream for stdout/err based on encoding. 1962 */ 1963 private static PrintStream newPrintStream(FileOutputStream fos, String enc) { 1964 if (enc != null) { 1965 try { 1966 return new PrintStream(new BufferedOutputStream(fos, 128), true, enc); 1967 } catch (UnsupportedEncodingException uee) {} 1968 } 1969 return new PrintStream(new BufferedOutputStream(fos, 128), true); 1970 } 1971 1972 1973 /** 1974 * Initialize the system class. Called after thread initialization. 1975 */ 1976 private static void initializeSystemClass() { 1977 1978 // VM might invoke JNU_NewStringPlatform() to set those encoding 1979 // sensitive properties (user.home, user.name, boot.class.path, etc.) 1980 // during "props" initialization, in which it may need access, via 1981 // System.getProperty(), to the related system encoding property that 1982 // have been initialized (put into "props") at early stage of the 1983 // initialization. So make sure the "props" is available at the 1984 // very beginning of the initialization and all system properties to 1985 // be put into it directly. 1986 props = new Properties(); 1987 initProperties(props); // initialized by the VM 1988 1989 // There are certain system configurations that may be controlled by 1990 // VM options such as the maximum amount of direct memory and 1991 // Integer cache size used to support the object identity semantics 1992 // of autoboxing. Typically, the library will obtain these values 1993 // from the properties set by the VM. If the properties are for 1994 // internal implementation use only, these properties should be 1995 // removed from the system properties. 1996 // 1997 // See java.lang.Integer.IntegerCache and the 1998 // sun.misc.VM.saveAndRemoveProperties method for example. 1999 // 2000 // Save a private copy of the system properties object that 2001 // can only be accessed by the internal implementation. Remove 2002 // certain system properties that are not intended for public access. 2003 sun.misc.VM.saveAndRemoveProperties(props); 2004 2005 2006 lineSeparator = props.getProperty("line.separator"); 2007 sun.misc.Version.init(); 2008 2009 FileInputStream fdIn = new FileInputStream(FileDescriptor.in); 2010 FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out); 2011 FileOutputStream fdErr = new FileOutputStream(FileDescriptor.err); 2012 setIn0(new BufferedInputStream(fdIn)); 2013 setOut0(newPrintStream(fdOut, props.getProperty("sun.stdout.encoding"))); 2014 setErr0(newPrintStream(fdErr, props.getProperty("sun.stderr.encoding"))); 2015 2016 // Load the zip library now in order to keep java.util.zip.ZipFile 2017 // from trying to use itself to load this library later. 2018 loadLibrary("zip"); 2019 2020 // Setup Java signal handlers for HUP, TERM, and INT (where available). 2021 Terminator.setup(); 2022 2023 // Initialize any miscellaneous operating system settings that need to be 2024 // set for the class libraries. Currently this is no-op everywhere except 2025 // for Windows where the process-wide error mode is set before the java.io 2026 // classes are used. 2027 sun.misc.VM.initializeOSEnvironment(); 2028 2029 // The main thread is not added to its thread group in the same 2030 // way as other threads; we must do it ourselves here. 2031 Thread current = Thread.currentThread(); 2032 current.getThreadGroup().add(current); 2033 2034 // register shared secrets 2035 setJavaLangAccess(); 2036 2037 // Subsystems that are invoked during initialization can invoke 2038 // sun.misc.VM.isBooted() in order to avoid doing things that should 2039 // wait until the application class loader has been set up. 2040 // IMPORTANT: Ensure that this remains the last initialization action! 2041 sun.misc.VM.booted(); 2042 } 2043 2044 private static void setJavaLangAccess() { 2045 // Allow privileged classes outside of java.lang 2046 SharedSecrets.setJavaLangAccess(new JavaLangAccess(){ 2047 public sun.reflect.ConstantPool getConstantPool(Class<?> klass) { 2048 return klass.getConstantPool(); 2049 } 2050 public boolean casAnnotationType(Class<?> klass, AnnotationType oldType, AnnotationType newType) { 2051 return klass.casAnnotationType(oldType, newType); 2052 } 2053 public AnnotationType getAnnotationType(Class<?> klass) { 2054 return klass.getAnnotationType(); 2055 } 2056 public Map<Class<? extends Annotation>, Annotation> getDeclaredAnnotationMap(Class<?> klass) { 2057 return klass.getDeclaredAnnotationMap(); 2058 } 2059 public byte[] getRawClassAnnotations(Class<?> klass) { 2060 return klass.getRawAnnotations(); 2061 } 2062 public byte[] getRawClassTypeAnnotations(Class<?> klass) { 2063 return klass.getRawTypeAnnotations(); 2064 } 2065 public byte[] getRawExecutableTypeAnnotations(Executable executable) { 2066 return Class.getExecutableTypeAnnotationBytes(executable); 2067 } 2068 public <E extends Enum<E>> 2069 E[] getEnumConstantsShared(Class<E> klass) { 2070 return klass.getEnumConstantsShared(); 2071 } 2072 public void blockedOn(Thread t, Interruptible b) { 2073 t.blockedOn(b); 2074 } 2075 public void registerShutdownHook(int slot, boolean registerShutdownInProgress, Runnable hook) { 2076 Shutdown.add(slot, registerShutdownInProgress, hook); 2077 } 2078 public int getStackTraceDepth(Throwable t) { 2079 return t.getStackTraceDepth(); 2080 } 2081 public StackTraceElement getStackTraceElement(Throwable t, int i) { 2082 return t.getStackTraceElement(i); 2083 } 2084 public String newStringUnsafe(char[] chars) { 2085 return new String(chars, true); 2086 } 2087 public Thread newThreadWithAcc(Runnable target, AccessControlContext acc) { 2088 return new Thread(target, acc); 2089 } 2090 public void invokeFinalize(Object o) throws Throwable { 2091 o.finalize(); 2092 } 2093 public void formatUnsignedLong(long val, int shift, char[] buf, int offset, int len) { 2094 Long.formatUnsignedLong(val, shift, buf, offset, len); 2095 } 2096 public void formatUnsignedInt(int val, int shift, char[] buf, int offset, int len) { 2097 Integer.formatUnsignedInt(val, shift, buf, offset, len); 2098 } 2099 }); 2100 } 2101 }