< prev index next >

jdk/src/java.base/share/classes/java/lang/System.java

Print this page




  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.StringTokenizer;
  34 import java.util.Map;
  35 import java.security.AccessController;
  36 import java.security.PrivilegedAction;
  37 import java.security.AllPermission;
  38 import java.nio.channels.Channel;
  39 import java.nio.channels.spi.SelectorProvider;



  40 import sun.nio.ch.Interruptible;
  41 import sun.reflect.CallerSensitive;
  42 import sun.reflect.Reflection;
  43 import sun.security.util.SecurityConstants;
  44 import sun.reflect.annotation.AnnotationType;
  45 import jdk.internal.HotSpotIntrinsicCandidate;
  46 import jdk.internal.misc.JavaLangAccess;;
  47 import jdk.internal.misc.SharedSecrets;;



  48 
  49 /**
  50  * The <code>System</code> class contains several useful class fields
  51  * and methods. It cannot be instantiated.
  52  *
  53  * <p>Among the facilities provided by the <code>System</code> class
  54  * are standard input, standard output, and error output streams;
  55  * access to externally defined properties and environment
  56  * variables; a means of loading files and libraries; and a utility
  57  * method for quickly copying a portion of an array.
  58  *
  59  * @author  unascribed
  60  * @since   1.0
  61  */
  62 public final class System {
  63 
  64     /* register the natives via the static initializer.
  65      *
  66      * VM will invoke the initializeSystemClass method to complete
  67      * the initialization for this class separated from clinit.


 927      *
 928      * @return the environment as a map of variable names to values
 929      * @throws SecurityException
 930      *         if a security manager exists and its
 931      *         {@link SecurityManager#checkPermission checkPermission}
 932      *         method doesn't allow access to the process environment
 933      * @see    #getenv(String)
 934      * @see    ProcessBuilder#environment()
 935      * @since  1.5
 936      */
 937     public static java.util.Map<String,String> getenv() {
 938         SecurityManager sm = getSecurityManager();
 939         if (sm != null) {
 940             sm.checkPermission(new RuntimePermission("getenv.*"));
 941         }
 942 
 943         return ProcessEnvironment.getenv();
 944     }
 945 
 946     /**


































































































































































































































































































































































































































































































































































































































































 947      * Terminates the currently running Java Virtual Machine. The
 948      * argument serves as a status code; by convention, a nonzero status
 949      * code indicates abnormal termination.
 950      * <p>
 951      * This method calls the <code>exit</code> method in class
 952      * <code>Runtime</code>. This method never returns normally.
 953      * <p>
 954      * The call <code>System.exit(n)</code> is effectively equivalent to
 955      * the call:
 956      * <blockquote><pre>
 957      * Runtime.getRuntime().exit(n)
 958      * </pre></blockquote>
 959      *
 960      * @param      status   exit status.
 961      * @throws  SecurityException
 962      *        if a security manager exists and its <code>checkExit</code>
 963      *        method doesn't allow exit with the specified status.
 964      * @see        java.lang.Runtime#exit(int)
 965      */
 966     public static void exit(int status) {




  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.util.function.Supplier;
  41 import sun.nio.ch.Interruptible;
  42 import sun.reflect.CallerSensitive;
  43 import sun.reflect.Reflection;
  44 import sun.security.util.SecurityConstants;
  45 import sun.reflect.annotation.AnnotationType;
  46 import jdk.internal.HotSpotIntrinsicCandidate;
  47 import jdk.internal.misc.JavaLangAccess;;
  48 import jdk.internal.misc.SharedSecrets;;
  49 import jdk.internal.logger.LoggerFinderLoader;
  50 import jdk.internal.logger.LazyLoggers;
  51 import jdk.internal.logger.LocalizedLoggerWrapper;
  52 
  53 /**
  54  * The <code>System</code> class contains several useful class fields
  55  * and methods. It cannot be instantiated.
  56  *
  57  * <p>Among the facilities provided by the <code>System</code> class
  58  * are standard input, standard output, and error output streams;
  59  * access to externally defined properties and environment
  60  * variables; a means of loading files and libraries; and a utility
  61  * method for quickly copying a portion of an array.
  62  *
  63  * @author  unascribed
  64  * @since   1.0
  65  */
  66 public final class System {
  67 
  68     /* register the natives via the static initializer.
  69      *
  70      * VM will invoke the initializeSystemClass method to complete
  71      * the initialization for this class separated from clinit.


 931      *
 932      * @return the environment as a map of variable names to values
 933      * @throws SecurityException
 934      *         if a security manager exists and its
 935      *         {@link SecurityManager#checkPermission checkPermission}
 936      *         method doesn't allow access to the process environment
 937      * @see    #getenv(String)
 938      * @see    ProcessBuilder#environment()
 939      * @since  1.5
 940      */
 941     public static java.util.Map<String,String> getenv() {
 942         SecurityManager sm = getSecurityManager();
 943         if (sm != null) {
 944             sm.checkPermission(new RuntimePermission("getenv.*"));
 945         }
 946 
 947         return ProcessEnvironment.getenv();
 948     }
 949 
 950     /**
 951      * {@code System.Logger} instances log messages that will be
 952      * routed to the underlying logging framework the {@link System.LoggerFinder
 953      * LoggerFinder} uses.
 954      * <p>
 955      * {@code System.Logger} instances are typically obtained from
 956      * the {@link java.lang.System System} class, by calling
 957      * {@link java.lang.System#getLogger(java.lang.String) System.getLogger(loggerName)}
 958      * or {@link java.lang.System#getLogger(java.lang.String, java.util.ResourceBundle)
 959      * System.getLogger(loggerName, bundle)}.
 960      *
 961      * @see java.lang.System#getLogger(java.lang.String)
 962      * @see java.lang.System#getLogger(java.lang.String, java.util.ResourceBundle)
 963      * @see java.lang.System.LoggerFinder
 964      *
 965      * @since 9
 966      *
 967      */
 968     public interface Logger {
 969 
 970         /**
 971          * System {@linkplain Logger loggers} levels.
 972          * <p>
 973          * A level has a {@linkplain #getName() name} and {@linkplain
 974          * #getSeverity() severity}.
 975          * Level values are {@link #ALL}, {@link #TRACE}, {@link #DEBUG},
 976          * {@link #INFO}, {@link #WARNING}, {@link #ERROR}, {@link #OFF},
 977          * by order of increasing severity.
 978          * <br>
 979          * {@link #ALL} and {@link #OFF}
 980          * are simple markers with severities mapped respectively to
 981          * {@link java.lang.Integer#MIN_VALUE Integer.MIN_VALUE} and
 982          * {@link java.lang.Integer#MAX_VALUE Integer.MAX_VALUE}.
 983          * <p>
 984          * <b>Severity values and Mapping to {@code java.util.logging.Level}.</b>
 985          * <p>
 986          * {@linkplain System.Logger.Level System logger levels} are mapped to
 987          * {@linkplain java.util.logging.Level  java.util.logging levels}
 988          * of corresponding severity.
 989          * <br>The mapping is as follows:
 990          * <br><br>
 991          * <table border="1">
 992          * <caption>System.Logger Severity Level Mapping</caption>
 993          * <tr><td><b>System.Logger Levels</b></td>
 994          * <td>{@link Logger.Level#ALL ALL}</td>
 995          * <td>{@link Logger.Level#TRACE TRACE}</td>
 996          * <td>{@link Logger.Level#DEBUG DEBUG}</td>
 997          * <td>{@link Logger.Level#INFO INFO}</td>
 998          * <td>{@link Logger.Level#WARNING WARNING}</td>
 999          * <td>{@link Logger.Level#ERROR ERROR}</td>
1000          * <td>{@link Logger.Level#OFF OFF}</td>
1001          * </tr>
1002          * <tr><td><b>java.util.logging Levels</b></td>
1003          * <td>{@link java.util.logging.Level#ALL ALL}</td>
1004          * <td>{@link java.util.logging.Level#FINER FINER}</td>
1005          * <td>{@link java.util.logging.Level#FINE FINE}</td>
1006          * <td>{@link java.util.logging.Level#INFO INFO}</td>
1007          * <td>{@link java.util.logging.Level#WARNING WARNING}</td>
1008          * <td>{@link java.util.logging.Level#SEVERE SEVERE}</td>
1009          * <td>{@link java.util.logging.Level#OFF OFF}</td>
1010          * </tr>
1011          * </table>
1012          *
1013          * @since 9
1014          *
1015          * @see java.lang.System.LoggerFinder
1016          * @see java.lang.System.Logger
1017          */
1018         public enum Level {
1019 
1020             // for convenience, we're reusing java.util.logging.Level int values
1021             // the mapping logic in sun.util.logging.PlatformLogger depends
1022             // on this.
1023             /**
1024              * A marker to indicate that all levels are enabled.
1025              * This level {@linkplain #getSeverity() severity} is
1026              * {@link Integer#MIN_VALUE}.
1027              */
1028             ALL(Integer.MIN_VALUE),  // typically mapped to/from j.u.l.Level.ALL
1029             /**
1030              * {@code TRACE} level: usually used to log diagnostic information.
1031              * This level {@linkplain #getSeverity() severity} is
1032              * {@code 400}.
1033              */
1034             TRACE(400),   // typically mapped to/from j.u.l.Level.FINER
1035             /**
1036              * {@code DEBUG} level: usually used to log debug information traces.
1037              * This level {@linkplain #getSeverity() severity} is
1038              * {@code 500}.
1039              */
1040             DEBUG(500),   // typically mapped to/from j.u.l.Level.FINEST/FINE/CONFIG
1041             /**
1042              * {@code INFO} level: usually used to log information messages.
1043              * This level {@linkplain #getSeverity() severity} is
1044              * {@code 800}.
1045              */
1046             INFO(800),    // typically mapped to/from j.u.l.Level.INFO
1047             /**
1048              * {@code WARNING} level: usually used to log warning messages.
1049              * This level {@linkplain #getSeverity() severity} is
1050              * {@code 900}.
1051              */
1052             WARNING(900), // typically mapped to/from j.u.l.Level.WARNING
1053             /**
1054              * {@code ERROR} level: usually used to log error messages.
1055              * This level {@linkplain #getSeverity() severity} is
1056              * {@code 1000}.
1057              */
1058             ERROR(1000),  // typically mapped to/from j.u.l.Level.SEVERE
1059             /**
1060              * A marker to indicate that all levels are disabled.
1061              * This level {@linkplain #getSeverity() severity} is
1062              * {@link Integer#MAX_VALUE}.
1063              */
1064             OFF(Integer.MAX_VALUE);  // typically mapped to/from j.u.l.Level.OFF
1065 
1066             private final int severity;
1067 
1068             private Level(int severity) {
1069                 this.severity = severity;
1070             }
1071 
1072             /**
1073              * Returns the name of this level.
1074              * @return this level {@linkplain #name()}.
1075              */
1076             public final String getName() {
1077                 return name();
1078             }
1079 
1080             /**
1081              * Returns the severity of this level.
1082              * A higher severity means a more severe condition.
1083              * @return this level severity.
1084              */
1085             public final int getSeverity() {
1086                 return severity;
1087             }
1088         }
1089 
1090         /**
1091          * Returns the name of this logger.
1092          *
1093          * @return the logger name.
1094          */
1095         public String getName();
1096 
1097         /**
1098          * Checks if a message of the given level would be logged by
1099          * this logger.
1100          *
1101          * @param level the log message level.
1102          * @return {@code true} if the given log message level is currently
1103          *         being logged.
1104          *
1105          * @throws NullPointerException if {@code level} is {@code null}.
1106          */
1107         public boolean isLoggable(Level level);
1108 
1109         /**
1110          * Logs a message.
1111          *
1112          * @implSpec The default implementation for this method calls
1113          * {@code this.log(level, (ResourceBundle)null, msg, (Object[])null);}
1114          *
1115          * @param level the log message level.
1116          * @param msg the string message (or a key in the message catalog, if
1117          * this logger is a {@link
1118          * LoggerFinder#getLocalizedLogger(java.lang.String, java.util.ResourceBundle, java.lang.Class)
1119          * localized logger}); can be {@code null}.
1120          *
1121          * @throws NullPointerException if {@code level} is {@code null}.
1122          */
1123         public default void log(Level level, String msg) {
1124             log(level, (ResourceBundle) null, msg, (Object[]) null);
1125         }
1126 
1127         /**
1128          * Logs a lazily supplied message.
1129          * <p>
1130          * If the logger is currently enabled for the given log message level
1131          * then a message is logged that is the result produced by the
1132          * given supplier function.  Otherwise, the supplier is not operated on.
1133          *
1134          * @implSpec When logging is enabled for the given level, the default
1135          * implementation for this method calls
1136          * {@code this.log(level, (ResourceBundle)null, msgSupplier.get(), (Object[])null);}
1137          *
1138          * @param level the log message level.
1139          * @param msgSupplier a supplier function that produces a message.
1140          *
1141          * @throws NullPointerException if {@code level} is {@code null},
1142          *         or {@code msgSupplier} is {@code null}.
1143          */
1144         public default void log(Level level, Supplier<String> msgSupplier) {
1145             Objects.requireNonNull(msgSupplier);
1146             if (isLoggable(Objects.requireNonNull(level))) {
1147                 log(level, (ResourceBundle) null, msgSupplier.get(), (Object[]) null);
1148             }
1149         }
1150 
1151         /**
1152          * Logs a message produced from the given object.
1153          * <p>
1154          * If the logger is currently enabled for the given log message level then
1155          * a message is logged that, by default, is the result produced from
1156          * calling  toString on the given object.
1157          * Otherwise, the object is not operated on.
1158          *
1159          * @implSpec When logging is enabled for the given level, the default
1160          * implementation for this method calls
1161          * {@code this.log(level, (ResourceBundle)null, obj.toString(), (Object[])null);}
1162          *
1163          * @param level the log message level.
1164          * @param obj the object to log.
1165          *
1166          * @throws NullPointerException if {@code level} is {@code null}, or
1167          *         {@code obj} is {@code null}.
1168          */
1169         public default void log(Level level, Object obj) {
1170             Objects.requireNonNull(obj);
1171             if (isLoggable(Objects.requireNonNull(level))) {
1172                 this.log(level, (ResourceBundle) null, obj.toString(), (Object[]) null);
1173             }
1174         }
1175 
1176         /**
1177          * Logs a message associated with a given throwable.
1178          *
1179          * @implSpec The default implementation for this method calls
1180          * {@code this.log(level, (ResourceBundle)null, msg, thrown);}
1181          *
1182          * @param level the log message level.
1183          * @param msg the string message (or a key in the message catalog, if
1184          * this logger is a {@link
1185          * LoggerFinder#getLocalizedLogger(java.lang.String, java.util.ResourceBundle, java.lang.Class)
1186          * localized logger}); can be {@code null}.
1187          * @param thrown a {@code Throwable} associated with the log message;
1188          *        can be {@code null}.
1189          *
1190          * @throws NullPointerException if {@code level} is {@code null}.
1191          */
1192         public default void log(Level level, String msg, Throwable thrown) {
1193             this.log(level, null, msg, thrown);
1194         }
1195 
1196         /**
1197          * Logs a lazily supplied message associated with a given throwable.
1198          * <p>
1199          * If the logger is currently enabled for the given log message level
1200          * then a message is logged that is the result produced by the
1201          * given supplier function.  Otherwise, the supplier is not operated on.
1202          *
1203          * @implSpec When logging is enabled for the given level, the default
1204          * implementation for this method calls
1205          * {@code this.log(level, (ResourceBundle)null, msgSupplier.get(), thrown);}
1206          *
1207          * @param level one of the log message level identifiers.
1208          * @param msgSupplier a supplier function that produces a message.
1209          * @param thrown a {@code Throwable} associated with log message;
1210          *               can be {@code null}.
1211          *
1212          * @throws NullPointerException if {@code level} is {@code null}, or
1213          *                               {@code msgSupplier} is {@code null}.
1214          */
1215         public default void log(Level level, Supplier<String> msgSupplier,
1216                 Throwable thrown) {
1217             Objects.requireNonNull(msgSupplier);
1218             if (isLoggable(Objects.requireNonNull(level))) {
1219                 this.log(level, null, msgSupplier.get(), thrown);
1220             }
1221         }
1222 
1223         /**
1224          * Logs a message with an optional list of parameters.
1225          *
1226          * @implSpec The default implementation for this method calls
1227          * {@code this.log(level, (ResourceBundle)null, format, params);}
1228          *
1229          * @param level one of the log message level identifiers.
1230          * @param format the string message format in {@link
1231          * java.text.MessageFormat} format, (or a key in the message
1232          * catalog, if this logger is a {@link
1233          * LoggerFinder#getLocalizedLogger(java.lang.String, java.util.ResourceBundle, java.lang.Class)
1234          * localized logger}); can be {@code null}.
1235          * @param params an optional list of parameters to the message (may be
1236          * none).
1237          *
1238          * @throws NullPointerException if {@code level} is {@code null}.
1239          */
1240         public default void log(Level level, String format, Object... params) {
1241             this.log(level, null, format, params);
1242         }
1243 
1244         /**
1245          * Logs a localized message associated with a given throwable.
1246          * <p>
1247          * If the given resource bundle is non-{@code null},  the {@code msg}
1248          * string is localized using the given resource bundle.
1249          * Otherwise the {@code msg} string is not localized.
1250          *
1251          * @param level the log message level.
1252          * @param bundle a resource bundle to localize {@code msg}; can be
1253          * {@code null}.
1254          * @param msg the string message (or a key in the message catalog,
1255          *            if {@code bundle} is not {@code null}); can be {@code null}.
1256          * @param thrown a {@code Throwable} associated with the log message;
1257          *        can be {@code null}.
1258          *
1259          * @throws NullPointerException if {@code level} is {@code null}.
1260          */
1261         public void log(Level level, ResourceBundle bundle, String msg,
1262                 Throwable thrown);
1263 
1264         /**
1265          * Logs a message with resource bundle and an optional list of
1266          * parameters.
1267          * <p>
1268          * If the given resource bundle is non-{@code null},  the {@code format}
1269          * string is localized using the given resource bundle.
1270          * Otherwise the {@code format} string is not localized.
1271          *
1272          * @param level the log message level.
1273          * @param bundle a resource bundle to localize {@code format}; can be
1274          * {@code null}.
1275          * @param format the string message format in {@link
1276          * java.text.MessageFormat} format, (or a key in the message
1277          * catalog if {@code bundle} is not {@code null}); can be {@code null}.
1278          * @param params an optional list of parameters to the message (may be
1279          * none).
1280          *
1281          * @throws NullPointerException if {@code level} is {@code null}.
1282          */
1283         public void log(Level level, ResourceBundle bundle, String format,
1284                 Object... params);
1285 
1286 
1287     }
1288 
1289     /**
1290      * The {@code LoggerFinder} service is responsible for creating, managing,
1291      * and configuring loggers to the underlying framework it uses.
1292      * <p>
1293      * A logger finder is a concrete implementation of this class that has a
1294      * zero-argument constructor and implements the abstract methods defined
1295      * by this class.
1296      * The loggers returned from a logger finder are capable of routing log
1297      * messages to the logging backend this provider supports.
1298      * A given invocation of the Java Runtime maintains a single
1299      * system-wide LoggerFinder instance that is loaded as follows:
1300      * <ul>
1301      *    <li>First it finds any custom {@code LoggerFinder} provider
1302      *        using the {@link java.util.ServiceLoader} facility with the
1303      *        {@linkplain ClassLoader#getSystemClassLoader() system class
1304      *        loader}.</li>
1305      *    <li>If no {@code LoggerFinder} provider is found, the system default
1306      *        {@code LoggerFinder} implementation will be used.</li>
1307      * </ul>
1308      * <p>
1309      * An application can replace the logging backend
1310      * <i>even when the java.logging module is present</i>, by simply providing
1311      * and declaring an implementation of the {@link LoggerFinder} service.
1312      * <p>
1313      * <b>Default Implementation</b>
1314      * <p>
1315      * The system default {@code LoggerFinder} implementation uses
1316      * {@code java.util.logging} as the backend framework when the
1317      * {@code java.logging} module is present.
1318      * It returns a {@linkplain System.Logger logger} instance
1319      * that will route log messages to a {@link java.util.logging.Logger
1320      * java.util.logging.Logger}. Otherwise, if {@code java.logging} is not
1321      * present, the default implementation will return a simple logger
1322      * instance that will route log messages of {@code INFO} level and above to
1323      * the console ({@code System.err}).
1324      * <p>
1325      * <b>Logging Configuration</b>
1326      * <p>
1327      * {@linkplain Logger Logger} instances obtained from the
1328      * {@code LoggerFinder} factory methods are not directly configurable by
1329      * the application. Configuration is the responsibility of the underlying
1330      * logging backend, and usually requires using APIs specific to that backend.
1331      * <p>For the default {@code LoggerFinder} implementation
1332      * using {@code java.util.logging} as its backend, refer to
1333      * {@link java.util.logging java.util.logging} for logging configuration.
1334      * For the default {@code LoggerFinder} implementation returning simple loggers
1335      * when the {@code java.logging} module is absent, the configuration
1336      * is implementation dependent.
1337      * <p>
1338      * Usually an application that uses a logging framework will log messages
1339      * through a logger facade defined (or supported) by that framework.
1340      * Applications that wish to use an external framework should log
1341      * through the facade associated with that framework.
1342      * <p>
1343      * A system class that needs to log messages will typically obtain
1344      * a {@link System.Logger} instance to route messages to the logging
1345      * framework selected by the application.
1346      * <p>
1347      * Libraries and classes that only need loggers to produce log messages
1348      * should not attempt to configure loggers by themselves, as that
1349      * would make them dependent from a specific implementation of the
1350      * {@code LoggerFinder} service.
1351      * <p>
1352      * In addition, when a security manager is present, loggers provided to
1353      * system classes should not be directly configurable through the logging
1354      * backend without requiring permissions.
1355      * <br>
1356      * It is the responsibility of the provider of
1357      * the concrete {@code LoggerFinder} implementation to ensure that
1358      * these loggers are not configured by untrusted code without proper
1359      * permission checks, as configuration performed on such loggers usually
1360      * affects all applications in the same Java Runtime.
1361      * <p>
1362      * <b>Message Levels and Mapping to backend levels</b>
1363      * <p>
1364      * A logger finder is responsible for mapping from a {@code
1365      * System.Logger.Level} to a level supported by the logging backend it uses.
1366      * <br>The default LoggerFinder using {@code java.util.logging} as the backend
1367      * maps {@code System.Logger} levels to
1368      * {@linkplain java.util.logging.Level java.util.logging} levels
1369      * of corresponding severity - as described in {@link Logger.Level
1370      * Logger.Level}.
1371      *
1372      * @see java.lang.System
1373      * @see java.lang.System.Logger
1374      *
1375      * @since 9
1376      */
1377     public static abstract class LoggerFinder {
1378         /**
1379          * The {@code RuntimePermission("loggerFinder")} is
1380          * necessary to subclass and instantiate the {@code LoggerFinder} class,
1381          * as well as to obtain loggers from an instance of that class.
1382          */
1383         static final RuntimePermission LOGGERFINDER_PERMISSION =
1384                 new RuntimePermission("loggerFinder");
1385 
1386         /**
1387          * Creates a new instance of {@code LoggerFinder}.
1388          *
1389          * @implNote It is recommended that a {@code LoggerFinder} service
1390          *   implementation does not perform any heavy initialization in its
1391          *   constructor, in order to avoid possible risks of deadlock or class
1392          *   loading cycles during the instantiation of the service provider.
1393          *
1394          * @throws SecurityException if a security manager is present and its
1395          *         {@code checkPermission} method doesn't allow the
1396          *         {@code RuntimePermission("loggerFinder")}.
1397          */
1398         protected LoggerFinder() {
1399             this(checkPermission());
1400         }
1401 
1402         private LoggerFinder(Void unused) {
1403             // nothing to do.
1404         }
1405 
1406         private static Void checkPermission() {
1407             final SecurityManager sm = System.getSecurityManager();
1408             if (sm != null) {
1409                 sm.checkPermission(LOGGERFINDER_PERMISSION);
1410             }
1411             return null;
1412         }
1413 
1414         /**
1415          * Returns an instance of {@link Logger Logger}
1416          * for the given {@code caller}.
1417          *
1418          * @param name the name of the logger.
1419          * @param caller the class for which the logger is being requested;
1420          *               can be {@code null}.
1421          *
1422          * @return a {@link Logger logger} suitable for the given caller's
1423          *         use.
1424          * @throws NullPointerException if {@code name} is {@code null} or
1425          *        {@code caller} is {@code null}.
1426          * @throws SecurityException if a security manager is present and its
1427          *         {@code checkPermission} method doesn't allow the
1428          *         {@code RuntimePermission("loggerFinder")}.
1429          */
1430         public abstract Logger getLogger(String name, /* Module */ Class<?> caller);
1431 
1432         /**
1433          * Returns a localizable instance of {@link Logger Logger}
1434          * for the given {@code caller}.
1435          * The returned logger will use the provided resource bundle for
1436          * message localization.
1437          *
1438          * @implSpec By default, this method calls {@link
1439          * #getLogger(java.lang.String, java.lang.Class)
1440          * this.getLogger(name, caller)} to obtain a logger, then wraps that
1441          * logger in a {@link Logger} instance where all methods that do not
1442          * take a {@link ResourceBundle} as parameter are redirected to one
1443          * which does - passing the given {@code bundle} for
1444          * localization. So for instance, a call to {@link
1445          * Logger#log(Level, String) Logger.log(Level.INFO, msg)}
1446          * will end up as a call to {@link
1447          * Logger#log(Level, ResourceBundle, String, Object...)
1448          * Logger.log(Level.INFO, bundle, msg, (Object[])null)} on the wrapped
1449          * logger instance.
1450          * Note however that by default, string messages returned by {@link
1451          * java.util.function.Supplier Supplier&lt;String&gt;} will not be
1452          * localized, as it is assumed that such strings are messages which are
1453          * already constructed, rather than keys in a resource bundle.
1454          * <p>
1455          * An implementation of {@code LoggerFinder} may override this method,
1456          * for example, when the underlying logging backend provides its own
1457          * mechanism for localizing log messages, then such a
1458          * {@code LoggerFinder} would be free to return a logger
1459          * that makes direct use of the mechanism provided by the backend.
1460          *
1461          * @param name    the name of the logger.
1462          * @param bundle  a resource bundle; can be {@code null}.
1463          * @param caller the class for which the logger is being requested.
1464          * @return an instance of {@link Logger Logger}  which will use the
1465          * provided resource bundle for message localization.
1466          *
1467          * @throws NullPointerException if {@code name} is {@code null} or
1468          *         {@code caller} is {@code null}.
1469          * @throws SecurityException if a security manager is present and its
1470          *         {@code checkPermission} method doesn't allow the
1471          *         {@code RuntimePermission("loggerFinder")}.
1472          */
1473         public Logger getLocalizedLogger(String name, ResourceBundle bundle,
1474                                           /* Module */ Class<?> caller) {
1475             return new LocalizedLoggerWrapper<>(getLogger(name, caller), bundle);
1476         }
1477 
1478         /**
1479          * Returns the {@code LoggerFinder} instance. There is one
1480          * single system-wide {@code LoggerFinder} instance in
1481          * the Java Runtime.  See the class specification of how the
1482          * {@link LoggerFinder LoggerFinder} implementation is located and
1483          * loaded.
1484 
1485          * @return the {@link LoggerFinder LoggerFinder} instance.
1486          * @throws SecurityException if a security manager is present and its
1487          *         {@code checkPermission} method doesn't allow the
1488          *         {@code RuntimePermission("loggerFinder")}.
1489          */
1490         public static LoggerFinder getLoggerFinder() {
1491             final SecurityManager sm = System.getSecurityManager();
1492             if (sm != null) {
1493                 sm.checkPermission(LOGGERFINDER_PERMISSION);
1494             }
1495             return accessProvider();
1496         }
1497 
1498 
1499         private static volatile LoggerFinder service;
1500         static LoggerFinder accessProvider() {
1501             // We do not need to synchronize: LoggerFinderLoader will
1502             // always return the same instance, so if we don't have it,
1503             // just fetch it again.
1504             if (service == null) {
1505                 PrivilegedAction<LoggerFinder> pa =
1506                         () -> LoggerFinderLoader.getLoggerFinder();
1507                 service = AccessController.doPrivileged(pa, null,
1508                         LOGGERFINDER_PERMISSION);
1509             }
1510             return service;
1511         }
1512 
1513     }
1514 
1515 
1516     /**
1517      * Returns an instance of {@link Logger Logger} for the caller's
1518      * use.
1519      *
1520      * @implSpec
1521      * Instances returned by this method route messages to loggers
1522      * obtained by calling {@link LoggerFinder#getLogger(java.lang.String, java.lang.Class)
1523      * LoggerFinder.getLogger(name, caller)}.
1524      *
1525      * @apiNote
1526      * This method may defer calling the {@link
1527      * LoggerFinder#getLogger(java.lang.String, java.lang.Class)
1528      * LoggerFinder.getLogger} method to create an actual logger supplied by
1529      * the logging backend, for instance, to allow loggers to be obtained during
1530      * the system initialization time.
1531      *
1532      * @param name the name of the logger.
1533      * @return an instance of {@link Logger} that can be used by the calling
1534      *         class.
1535      * @throws NullPointerException if {@code name} is {@code null}.
1536      */
1537     @CallerSensitive
1538     public static Logger getLogger(String name) {
1539         Objects.requireNonNull(name);
1540         final Class<?> caller = Reflection.getCallerClass();
1541         return LazyLoggers.getLogger(name, caller);
1542     }
1543 
1544     /**
1545      * Returns a localizable instance of {@link Logger
1546      * Logger} for the caller's use.
1547      * The returned logger will use the provided resource bundle for message
1548      * localization.
1549      *
1550      * @implSpec
1551      * The returned logger will perform message localization as specified
1552      * by {@link LoggerFinder#getLocalizedLogger(java.lang.String,
1553      * java.util.ResourceBundle, java.lang.Class)
1554      * LoggerFinder.getLocalizedLogger(name, bundle, caller}.
1555      *
1556      * @apiNote
1557      * This method is intended to be used after the system is fully initialized.
1558      * This method may trigger the immediate loading and initialization
1559      * of the {@link LoggerFinder} service, which may cause issues if the
1560      * Java Runtime is not ready to initialize the concrete service
1561      * implementation yet.
1562      * System classes which may be loaded early in the boot sequence and
1563      * need to log localized messages should create a logger using
1564      * {@link #getLogger(java.lang.String)} and then use the log methods that
1565      * take a resource bundle as parameter.
1566      *
1567      * @param name    the name of the logger.
1568      * @param bundle  a resource bundle.
1569      * @return an instance of {@link Logger} which will use the provided
1570      * resource bundle for message localization.
1571      * @throws NullPointerException if {@code name} is {@code null} or
1572      *         {@code bundle} is {@code null}.
1573      */
1574     @CallerSensitive
1575     public static Logger getLogger(String name, ResourceBundle bundle) {
1576         final ResourceBundle rb = Objects.requireNonNull(bundle);
1577         Objects.requireNonNull(name);
1578         final Class<?> caller = Reflection.getCallerClass();
1579         final SecurityManager sm = System.getSecurityManager();
1580         // We don't use LazyLoggers if a resource bundle is specified.
1581         // Bootstrap sensitive classes in the JDK do not use resource bundles
1582         // when logging. This could be revisited later, if it needs to.
1583         if (sm != null) {
1584             return AccessController.doPrivileged((PrivilegedAction<Logger>)
1585                     () -> LoggerFinder.accessProvider().getLocalizedLogger(name, rb, caller),
1586                     null,
1587                     LoggerFinder.LOGGERFINDER_PERMISSION);
1588         }
1589         return LoggerFinder.accessProvider().getLocalizedLogger(name, rb, caller);
1590     }
1591 
1592     /**
1593      * Terminates the currently running Java Virtual Machine. The
1594      * argument serves as a status code; by convention, a nonzero status
1595      * code indicates abnormal termination.
1596      * <p>
1597      * This method calls the <code>exit</code> method in class
1598      * <code>Runtime</code>. This method never returns normally.
1599      * <p>
1600      * The call <code>System.exit(n)</code> is effectively equivalent to
1601      * the call:
1602      * <blockquote><pre>
1603      * Runtime.getRuntime().exit(n)
1604      * </pre></blockquote>
1605      *
1606      * @param      status   exit status.
1607      * @throws  SecurityException
1608      *        if a security manager exists and its <code>checkExit</code>
1609      *        method doesn't allow exit with the specified status.
1610      * @see        java.lang.Runtime#exit(int)
1611      */
1612     public static void exit(int status) {


< prev index next >