src/share/classes/java/util/logging/Logger.java

Print this page




 321         LogManager.getLogManager();
 322 
 323         // Now the global LogManager should be initialized,
 324         // and the global logger should have been added to
 325         // it, unless we were called within the constructor of a LogManager
 326         // subclass installed as LogManager, in which case global.manager
 327         // would still be null, and global will be lazily initialized later on.
 328 
 329         return global;
 330     }
 331 
 332     /**
 333      * The "global" Logger object is provided as a convenience to developers
 334      * who are making casual use of the Logging package.  Developers
 335      * who are making serious use of the logging package (for example
 336      * in products) should create and use their own Logger objects,
 337      * with appropriate names, so that logging can be controlled on a
 338      * suitable per-Logger granularity. Developers also need to keep a
 339      * strong reference to their Logger objects to prevent them from
 340      * being garbage collected.
 341      * <p>
 342      * @deprecated Initialization of this field is prone to deadlocks.
 343      * The field must be initialized by the Logger class initialization
 344      * which may cause deadlocks with the LogManager class initialization.
 345      * In such cases two class initialization wait for each other to complete.
 346      * The preferred way to get the global logger object is via the call
 347      * <code>Logger.getGlobal()</code>.
 348      * For compatibility with old JDK versions where the
 349      * <code>Logger.getGlobal()</code> is not available use the call
 350      * <code>Logger.getLogger(Logger.GLOBAL_LOGGER_NAME)</code>
 351      * or <code>Logger.getLogger("global")</code>.
 352      */
 353     @Deprecated
 354     public static final Logger global = new Logger(GLOBAL_LOGGER_NAME);
 355 
 356     /**
 357      * Protected method to construct a logger for a named subsystem.
 358      * <p>
 359      * The logger will be initially configured with a null Level
 360      * and with useParentHandlers set to true.
 361      *


 509      * <p>
 510      * If a new logger is created its log level will be configured
 511      * based on the LogManager and it will configured to also send logging
 512      * output to its parent's Handlers.  It will be registered in
 513      * the LogManager global namespace.
 514      * <p>
 515      * Note: The LogManager may only retain a weak reference to the newly
 516      * created Logger. It is important to understand that a previously
 517      * created Logger with the given name may be garbage collected at any
 518      * time if there is no strong reference to the Logger. In particular,
 519      * this means that two back-to-back calls like
 520      * {@code getLogger("MyLogger", ...).log(...)} may use different Logger
 521      * objects named "MyLogger" if there is no strong reference to the
 522      * Logger named "MyLogger" elsewhere in the program.
 523      * <p>
 524      * If the named Logger already exists and does not yet have a
 525      * localization resource bundle then the given resource bundle
 526      * name is used.  If the named Logger already exists and has
 527      * a different resource bundle name then an IllegalArgumentException
 528      * is thrown.
 529      * <p>
 530      * @param   name    A name for the logger.  This should
 531      *                          be a dot-separated name and should normally
 532      *                          be based on the package name or class name
 533      *                          of the subsystem, such as java.net
 534      *                          or javax.swing
 535      * @param   resourceBundleName  name of ResourceBundle to be used for localizing
 536      *                          messages for this logger. May be {@code null}
 537      *                          if none of the messages require localization.
 538      * @return a suitable Logger
 539      * @throws MissingResourceException if the resourceBundleName is non-null and
 540      *             no corresponding resource can be found.
 541      * @throws IllegalArgumentException if the Logger already exists and uses
 542      *             a different resource bundle name; or if
 543      *             {@code resourceBundleName} is {@code null} but the named
 544      *             logger has a resource bundle set.
 545      * @throws NullPointerException if the name is null.
 546      */
 547 
 548     // Synchronization is not required here. All synchronization for
 549     // adding a new Logger object is handled by LogManager.addLogger().


 578     }
 579 
 580     /**
 581      * Create an anonymous Logger.  The newly created Logger is not
 582      * registered in the LogManager namespace.  There will be no
 583      * access checks on updates to the logger.
 584      * <p>
 585      * This factory method is primarily intended for use from applets.
 586      * Because the resulting Logger is anonymous it can be kept private
 587      * by the creating class.  This removes the need for normal security
 588      * checks, which in turn allows untrusted applet code to update
 589      * the control state of the Logger.  For example an applet can do
 590      * a setLevel or an addHandler on an anonymous Logger.
 591      * <p>
 592      * Even although the new logger is anonymous, it is configured
 593      * to have the root logger ("") as its parent.  This means that
 594      * by default it inherits its effective level and handlers
 595      * from the root logger. Changing its parent via the
 596      * {@link #setParent(java.util.logging.Logger) setParent} method
 597      * will still require the security permission specified by that method.
 598      * <p>
 599      *
 600      * @return a newly created private Logger
 601      */
 602     public static Logger getAnonymousLogger() {
 603         return getAnonymousLogger(null);
 604     }
 605 
 606     /**
 607      * Create an anonymous Logger.  The newly created Logger is not
 608      * registered in the LogManager namespace.  There will be no
 609      * access checks on updates to the logger.
 610      * <p>
 611      * This factory method is primarily intended for use from applets.
 612      * Because the resulting Logger is anonymous it can be kept private
 613      * by the creating class.  This removes the need for normal security
 614      * checks, which in turn allows untrusted applet code to update
 615      * the control state of the Logger.  For example an applet can do
 616      * a setLevel or an addHandler on an anonymous Logger.
 617      * <p>
 618      * Even although the new logger is anonymous, it is configured
 619      * to have the root logger ("") as its parent.  This means that
 620      * by default it inherits its effective level and handlers
 621      * from the root logger.  Changing its parent via the
 622      * {@link #setParent(java.util.logging.Logger) setParent} method
 623      * will still require the security permission specified by that method.
 624      * <p>
 625      * @param   resourceBundleName  name of ResourceBundle to be used for localizing
 626      *                          messages for this logger.
 627      *          May be null if none of the messages require localization.
 628      * @return a newly created private Logger
 629      * @throws MissingResourceException if the resourceBundleName is non-null and
 630      *             no corresponding resource can be found.
 631      */
 632 
 633     // Synchronization is not required here. All synchronization for
 634     // adding a new anonymous Logger object is handled by doSetParent().
 635     @CallerSensitive
 636     public static Logger getAnonymousLogger(String resourceBundleName) {
 637         LogManager manager = LogManager.getLogManager();
 638         // cleanup some Loggers that have been GC'ed
 639         manager.drainLoggerRefQueueBounded();
 640         Logger result = new Logger(null, resourceBundleName,
 641                                    Reflection.getCallerClass(), manager, false);
 642         result.anonymous = true;
 643         Logger root = manager.getLogger("");
 644         result.doSetParent(root);


 759         final ResourceBundle  bundle = lb.userBundle;
 760         final String ebname = lb.resourceBundleName;
 761         if (ebname != null && bundle != null) {
 762             lr.setResourceBundleName(ebname);
 763             lr.setResourceBundle(bundle);
 764         }
 765         log(lr);
 766     }
 767 
 768 
 769     //================================================================
 770     // Start of convenience methods WITHOUT className and methodName
 771     //================================================================
 772 
 773     /**
 774      * Log a message, with no arguments.
 775      * <p>
 776      * If the logger is currently enabled for the given message
 777      * level then the given message is forwarded to all the
 778      * registered output Handler objects.
 779      * <p>
 780      * @param   level   One of the message level identifiers, e.g., SEVERE
 781      * @param   msg     The string message (or a key in the message catalog)
 782      */
 783     public void log(Level level, String msg) {
 784         if (!isLoggable(level)) {
 785             return;
 786         }
 787         LogRecord lr = new LogRecord(level, msg);
 788         doLog(lr);
 789     }
 790 
 791     /**
 792      * Log a message, which is only to be constructed if the logging level
 793      * is such that the message will actually be logged.
 794      * <p>
 795      * If the logger is currently enabled for the given message
 796      * level then the message is constructed by invoking the provided
 797      * supplier function and forwarded to all the registered output
 798      * Handler objects.
 799      * <p>
 800      * @param   level   One of the message level identifiers, e.g., SEVERE
 801      * @param   msgSupplier   A function, which when called, produces the
 802      *                        desired log message
 803      */
 804     public void log(Level level, Supplier<String> msgSupplier) {
 805         if (!isLoggable(level)) {
 806             return;
 807         }
 808         LogRecord lr = new LogRecord(level, msgSupplier.get());
 809         doLog(lr);
 810     }
 811 
 812     /**
 813      * Log a message, with one object parameter.
 814      * <p>
 815      * If the logger is currently enabled for the given message
 816      * level then a corresponding LogRecord is created and forwarded
 817      * to all the registered output Handler objects.
 818      * <p>
 819      * @param   level   One of the message level identifiers, e.g., SEVERE
 820      * @param   msg     The string message (or a key in the message catalog)
 821      * @param   param1  parameter to the message
 822      */
 823     public void log(Level level, String msg, Object param1) {
 824         if (!isLoggable(level)) {
 825             return;
 826         }
 827         LogRecord lr = new LogRecord(level, msg);
 828         Object params[] = { param1 };
 829         lr.setParameters(params);
 830         doLog(lr);
 831     }
 832 
 833     /**
 834      * Log a message, with an array of object arguments.
 835      * <p>
 836      * If the logger is currently enabled for the given message
 837      * level then a corresponding LogRecord is created and forwarded
 838      * to all the registered output Handler objects.
 839      * <p>
 840      * @param   level   One of the message level identifiers, e.g., SEVERE
 841      * @param   msg     The string message (or a key in the message catalog)
 842      * @param   params  array of parameters to the message
 843      */
 844     public void log(Level level, String msg, Object params[]) {
 845         if (!isLoggable(level)) {
 846             return;
 847         }
 848         LogRecord lr = new LogRecord(level, msg);
 849         lr.setParameters(params);
 850         doLog(lr);
 851     }
 852 
 853     /**
 854      * Log a message, with associated Throwable information.
 855      * <p>
 856      * If the logger is currently enabled for the given message
 857      * level then the given arguments are stored in a LogRecord
 858      * which is forwarded to all registered output handlers.
 859      * <p>
 860      * Note that the thrown argument is stored in the LogRecord thrown
 861      * property, rather than the LogRecord parameters property.  Thus it is
 862      * processed specially by output Formatters and is not treated
 863      * as a formatting parameter to the LogRecord message property.
 864      * <p>
 865      * @param   level   One of the message level identifiers, e.g., SEVERE
 866      * @param   msg     The string message (or a key in the message catalog)
 867      * @param   thrown  Throwable associated with log message.
 868      */
 869     public void log(Level level, String msg, Throwable thrown) {
 870         if (!isLoggable(level)) {
 871             return;
 872         }
 873         LogRecord lr = new LogRecord(level, msg);
 874         lr.setThrown(thrown);
 875         doLog(lr);
 876     }
 877 
 878     /**
 879      * Log a lazily constructed message, with associated Throwable information.
 880      * <p>
 881      * If the logger is currently enabled for the given message level then the
 882      * message is constructed by invoking the provided supplier function. The
 883      * message and the given {@link Throwable} are then stored in a {@link
 884      * LogRecord} which is forwarded to all registered output handlers.
 885      * <p>
 886      * Note that the thrown argument is stored in the LogRecord thrown
 887      * property, rather than the LogRecord parameters property.  Thus it is
 888      * processed specially by output Formatters and is not treated
 889      * as a formatting parameter to the LogRecord message property.
 890      * <p>
 891      * @param   level   One of the message level identifiers, e.g., SEVERE
 892      * @param   thrown  Throwable associated with log message.
 893      * @param   msgSupplier   A function, which when called, produces the
 894      *                        desired log message
 895      * @since   1.8
 896      */
 897     public void log(Level level, Throwable thrown, Supplier<String> msgSupplier) {
 898         if (!isLoggable(level)) {
 899             return;
 900         }
 901         LogRecord lr = new LogRecord(level, msgSupplier.get());
 902         lr.setThrown(thrown);
 903         doLog(lr);
 904     }
 905 
 906     //================================================================
 907     // Start of convenience methods WITH className and methodName
 908     //================================================================
 909 
 910     /**
 911      * Log a message, specifying source class and method,
 912      * with no arguments.
 913      * <p>
 914      * If the logger is currently enabled for the given message
 915      * level then the given message is forwarded to all the
 916      * registered output Handler objects.
 917      * <p>
 918      * @param   level   One of the message level identifiers, e.g., SEVERE
 919      * @param   sourceClass    name of class that issued the logging request
 920      * @param   sourceMethod   name of method that issued the logging request
 921      * @param   msg     The string message (or a key in the message catalog)
 922      */
 923     public void logp(Level level, String sourceClass, String sourceMethod, String msg) {
 924         if (!isLoggable(level)) {
 925             return;
 926         }
 927         LogRecord lr = new LogRecord(level, msg);
 928         lr.setSourceClassName(sourceClass);
 929         lr.setSourceMethodName(sourceMethod);
 930         doLog(lr);
 931     }
 932 
 933     /**
 934      * Log a lazily constructed message, specifying source class and method,
 935      * with no arguments.
 936      * <p>
 937      * If the logger is currently enabled for the given message
 938      * level then the message is constructed by invoking the provided
 939      * supplier function and forwarded to all the registered output
 940      * Handler objects.
 941      * <p>
 942      * @param   level   One of the message level identifiers, e.g., SEVERE
 943      * @param   sourceClass    name of class that issued the logging request
 944      * @param   sourceMethod   name of method that issued the logging request
 945      * @param   msgSupplier   A function, which when called, produces the
 946      *                        desired log message
 947      * @since   1.8
 948      */
 949     public void logp(Level level, String sourceClass, String sourceMethod,
 950                      Supplier<String> msgSupplier) {
 951         if (!isLoggable(level)) {
 952             return;
 953         }
 954         LogRecord lr = new LogRecord(level, msgSupplier.get());
 955         lr.setSourceClassName(sourceClass);
 956         lr.setSourceMethodName(sourceMethod);
 957         doLog(lr);
 958     }
 959 
 960     /**
 961      * Log a message, specifying source class and method,
 962      * with a single object parameter to the log message.
 963      * <p>
 964      * If the logger is currently enabled for the given message
 965      * level then a corresponding LogRecord is created and forwarded
 966      * to all the registered output Handler objects.
 967      * <p>
 968      * @param   level   One of the message level identifiers, e.g., SEVERE
 969      * @param   sourceClass    name of class that issued the logging request
 970      * @param   sourceMethod   name of method that issued the logging request
 971      * @param   msg      The string message (or a key in the message catalog)
 972      * @param   param1    Parameter to the log message.
 973      */
 974     public void logp(Level level, String sourceClass, String sourceMethod,
 975                                                 String msg, Object param1) {
 976         if (!isLoggable(level)) {
 977             return;
 978         }
 979         LogRecord lr = new LogRecord(level, msg);
 980         lr.setSourceClassName(sourceClass);
 981         lr.setSourceMethodName(sourceMethod);
 982         Object params[] = { param1 };
 983         lr.setParameters(params);
 984         doLog(lr);
 985     }
 986 
 987     /**
 988      * Log a message, specifying source class and method,
 989      * with an array of object arguments.
 990      * <p>
 991      * If the logger is currently enabled for the given message
 992      * level then a corresponding LogRecord is created and forwarded
 993      * to all the registered output Handler objects.
 994      * <p>
 995      * @param   level   One of the message level identifiers, e.g., SEVERE
 996      * @param   sourceClass    name of class that issued the logging request
 997      * @param   sourceMethod   name of method that issued the logging request
 998      * @param   msg     The string message (or a key in the message catalog)
 999      * @param   params  Array of parameters to the message
1000      */
1001     public void logp(Level level, String sourceClass, String sourceMethod,
1002                                                 String msg, Object params[]) {
1003         if (!isLoggable(level)) {
1004             return;
1005         }
1006         LogRecord lr = new LogRecord(level, msg);
1007         lr.setSourceClassName(sourceClass);
1008         lr.setSourceMethodName(sourceMethod);
1009         lr.setParameters(params);
1010         doLog(lr);
1011     }
1012 
1013     /**
1014      * Log a message, specifying source class and method,
1015      * with associated Throwable information.
1016      * <p>
1017      * If the logger is currently enabled for the given message
1018      * level then the given arguments are stored in a LogRecord
1019      * which is forwarded to all registered output handlers.
1020      * <p>
1021      * Note that the thrown argument is stored in the LogRecord thrown
1022      * property, rather than the LogRecord parameters property.  Thus it is
1023      * processed specially by output Formatters and is not treated
1024      * as a formatting parameter to the LogRecord message property.
1025      * <p>
1026      * @param   level   One of the message level identifiers, e.g., SEVERE
1027      * @param   sourceClass    name of class that issued the logging request
1028      * @param   sourceMethod   name of method that issued the logging request
1029      * @param   msg     The string message (or a key in the message catalog)
1030      * @param   thrown  Throwable associated with log message.
1031      */
1032     public void logp(Level level, String sourceClass, String sourceMethod,
1033                      String msg, Throwable thrown) {
1034         if (!isLoggable(level)) {
1035             return;
1036         }
1037         LogRecord lr = new LogRecord(level, msg);
1038         lr.setSourceClassName(sourceClass);
1039         lr.setSourceMethodName(sourceMethod);
1040         lr.setThrown(thrown);
1041         doLog(lr);
1042     }
1043 
1044     /**
1045      * Log a lazily constructed message, specifying source class and method,
1046      * with associated Throwable information.
1047      * <p>
1048      * If the logger is currently enabled for the given message level then the
1049      * message is constructed by invoking the provided supplier function. The
1050      * message and the given {@link Throwable} are then stored in a {@link
1051      * LogRecord} which is forwarded to all registered output handlers.
1052      * <p>
1053      * Note that the thrown argument is stored in the LogRecord thrown
1054      * property, rather than the LogRecord parameters property.  Thus it is
1055      * processed specially by output Formatters and is not treated
1056      * as a formatting parameter to the LogRecord message property.
1057      * <p>
1058      * @param   level   One of the message level identifiers, e.g., SEVERE
1059      * @param   sourceClass    name of class that issued the logging request
1060      * @param   sourceMethod   name of method that issued the logging request
1061      * @param   thrown  Throwable associated with log message.
1062      * @param   msgSupplier   A function, which when called, produces the
1063      *                        desired log message
1064      * @since   1.8
1065      */
1066     public void logp(Level level, String sourceClass, String sourceMethod,
1067                      Throwable thrown, Supplier<String> msgSupplier) {
1068         if (!isLoggable(level)) {
1069             return;
1070         }
1071         LogRecord lr = new LogRecord(level, msgSupplier.get());
1072         lr.setSourceClassName(sourceClass);
1073         lr.setSourceMethodName(sourceMethod);
1074         lr.setThrown(thrown);
1075         doLog(lr);
1076     }
1077 


1096     private void doLog(LogRecord lr, ResourceBundle rb) {
1097         lr.setLoggerName(name);
1098         if (rb != null) {
1099             lr.setResourceBundleName(rb.getBaseBundleName());
1100             lr.setResourceBundle(rb);
1101         }
1102         log(lr);
1103     }
1104 
1105     /**
1106      * Log a message, specifying source class, method, and resource bundle name
1107      * with no arguments.
1108      * <p>
1109      * If the logger is currently enabled for the given message
1110      * level then the given message is forwarded to all the
1111      * registered output Handler objects.
1112      * <p>
1113      * The msg string is localized using the named resource bundle.  If the
1114      * resource bundle name is null, or an empty String or invalid
1115      * then the msg string is not localized.
1116      * <p>
1117      * @param   level   One of the message level identifiers, e.g., SEVERE
1118      * @param   sourceClass    name of class that issued the logging request
1119      * @param   sourceMethod   name of method that issued the logging request
1120      * @param   bundleName     name of resource bundle to localize msg,
1121      *                         can be null
1122      * @param   msg     The string message (or a key in the message catalog)
1123      * @deprecated Use {@link #logrb(java.util.logging.Level, java.lang.String,
1124      * java.lang.String, java.util.ResourceBundle, java.lang.String,
1125      * java.lang.Object...)} instead.
1126      */
1127     @Deprecated
1128     public void logrb(Level level, String sourceClass, String sourceMethod,
1129                                 String bundleName, String msg) {
1130         if (!isLoggable(level)) {
1131             return;
1132         }
1133         LogRecord lr = new LogRecord(level, msg);
1134         lr.setSourceClassName(sourceClass);
1135         lr.setSourceMethodName(sourceMethod);
1136         doLog(lr, bundleName);
1137     }
1138 
1139     /**
1140      * Log a message, specifying source class, method, and resource bundle name,
1141      * with a single object parameter to the log message.
1142      * <p>
1143      * If the logger is currently enabled for the given message
1144      * level then a corresponding LogRecord is created and forwarded
1145      * to all the registered output Handler objects.
1146      * <p>
1147      * The msg string is localized using the named resource bundle.  If the
1148      * resource bundle name is null, or an empty String or invalid
1149      * then the msg string is not localized.
1150      * <p>
1151      * @param   level   One of the message level identifiers, e.g., SEVERE
1152      * @param   sourceClass    name of class that issued the logging request
1153      * @param   sourceMethod   name of method that issued the logging request
1154      * @param   bundleName     name of resource bundle to localize msg,
1155      *                         can be null
1156      * @param   msg      The string message (or a key in the message catalog)
1157      * @param   param1    Parameter to the log message.
1158      * @deprecated Use {@link #logrb(java.util.logging.Level, java.lang.String,
1159      *   java.lang.String, java.util.ResourceBundle, java.lang.String,
1160      *   java.lang.Object...)} instead
1161      */
1162     @Deprecated
1163     public void logrb(Level level, String sourceClass, String sourceMethod,
1164                                 String bundleName, String msg, Object param1) {
1165         if (!isLoggable(level)) {
1166             return;
1167         }
1168         LogRecord lr = new LogRecord(level, msg);
1169         lr.setSourceClassName(sourceClass);
1170         lr.setSourceMethodName(sourceMethod);
1171         Object params[] = { param1 };
1172         lr.setParameters(params);
1173         doLog(lr, bundleName);
1174     }
1175 
1176     /**
1177      * Log a message, specifying source class, method, and resource bundle name,
1178      * with an array of object arguments.
1179      * <p>
1180      * If the logger is currently enabled for the given message
1181      * level then a corresponding LogRecord is created and forwarded
1182      * to all the registered output Handler objects.
1183      * <p>
1184      * The msg string is localized using the named resource bundle.  If the
1185      * resource bundle name is null, or an empty String or invalid
1186      * then the msg string is not localized.
1187      * <p>
1188      * @param   level   One of the message level identifiers, e.g., SEVERE
1189      * @param   sourceClass    name of class that issued the logging request
1190      * @param   sourceMethod   name of method that issued the logging request
1191      * @param   bundleName     name of resource bundle to localize msg,
1192      *                         can be null.
1193      * @param   msg     The string message (or a key in the message catalog)
1194      * @param   params  Array of parameters to the message
1195      * @deprecated Use {@link #logrb(java.util.logging.Level, java.lang.String,
1196      *      java.lang.String, java.util.ResourceBundle, java.lang.String,
1197      *      java.lang.Object...)} instead.
1198      */
1199     @Deprecated
1200     public void logrb(Level level, String sourceClass, String sourceMethod,
1201                                 String bundleName, String msg, Object params[]) {
1202         if (!isLoggable(level)) {
1203             return;
1204         }
1205         LogRecord lr = new LogRecord(level, msg);
1206         lr.setSourceClassName(sourceClass);
1207         lr.setSourceMethodName(sourceMethod);
1208         lr.setParameters(params);
1209         doLog(lr, bundleName);
1210     }
1211 
1212     /**
1213      * Log a message, specifying source class, method, and resource bundle,
1214      * with an optional list of message parameters.
1215      * <p>
1216      * If the logger is currently enabled for the given message
1217      * level then a corresponding LogRecord is created and forwarded
1218      * to all the registered output Handler objects.
1219      * <p>
1220      * The {@code msg} string is localized using the given resource bundle.
1221      * If the resource bundle is {@code null}, then the {@code msg} string is not
1222      * localized.
1223      * <p>
1224      * @param   level   One of the message level identifiers, e.g., SEVERE
1225      * @param   sourceClass    Name of the class that issued the logging request
1226      * @param   sourceMethod   Name of the method that issued the logging request
1227      * @param   bundle         Resource bundle to localize {@code msg},
1228      *                         can be {@code null}.
1229      * @param   msg     The string message (or a key in the message catalog)
1230      * @param   params  Parameters to the message (optional, may be none).
1231      * @since 1.8
1232      */
1233     public void logrb(Level level, String sourceClass, String sourceMethod,
1234                       ResourceBundle bundle, String msg, Object... params) {
1235         if (!isLoggable(level)) {
1236             return;
1237         }
1238         LogRecord lr = new LogRecord(level, msg);
1239         lr.setSourceClassName(sourceClass);
1240         lr.setSourceMethodName(sourceMethod);
1241         if (params != null && params.length != 0) {
1242             lr.setParameters(params);
1243         }
1244         doLog(lr, bundle);
1245     }
1246 
1247     /**
1248      * Log a message, specifying source class, method, and resource bundle name,
1249      * with associated Throwable information.
1250      * <p>
1251      * If the logger is currently enabled for the given message
1252      * level then the given arguments are stored in a LogRecord
1253      * which is forwarded to all registered output handlers.
1254      * <p>
1255      * The msg string is localized using the named resource bundle.  If the
1256      * resource bundle name is null, or an empty String or invalid
1257      * then the msg string is not localized.
1258      * <p>
1259      * Note that the thrown argument is stored in the LogRecord thrown
1260      * property, rather than the LogRecord parameters property.  Thus it is
1261      * processed specially by output Formatters and is not treated
1262      * as a formatting parameter to the LogRecord message property.
1263      * <p>
1264      * @param   level   One of the message level identifiers, e.g., SEVERE
1265      * @param   sourceClass    name of class that issued the logging request
1266      * @param   sourceMethod   name of method that issued the logging request
1267      * @param   bundleName     name of resource bundle to localize msg,
1268      *                         can be null
1269      * @param   msg     The string message (or a key in the message catalog)
1270      * @param   thrown  Throwable associated with log message.
1271      * @deprecated Use {@link #logrb(java.util.logging.Level, java.lang.String,
1272      *     java.lang.String, java.util.ResourceBundle, java.lang.String,
1273      *     java.lang.Throwable)} instead.
1274      */
1275     @Deprecated
1276     public void logrb(Level level, String sourceClass, String sourceMethod,
1277                                         String bundleName, String msg, Throwable thrown) {
1278         if (!isLoggable(level)) {
1279             return;
1280         }
1281         LogRecord lr = new LogRecord(level, msg);
1282         lr.setSourceClassName(sourceClass);
1283         lr.setSourceMethodName(sourceMethod);
1284         lr.setThrown(thrown);
1285         doLog(lr, bundleName);
1286     }
1287 
1288     /**
1289      * Log a message, specifying source class, method, and resource bundle,
1290      * with associated Throwable information.
1291      * <p>
1292      * If the logger is currently enabled for the given message
1293      * level then the given arguments are stored in a LogRecord
1294      * which is forwarded to all registered output handlers.
1295      * <p>
1296      * The {@code msg} string is localized using the given resource bundle.
1297      * If the resource bundle is {@code null}, then the {@code msg} string is not
1298      * localized.
1299      * <p>
1300      * Note that the thrown argument is stored in the LogRecord thrown
1301      * property, rather than the LogRecord parameters property.  Thus it is
1302      * processed specially by output Formatters and is not treated
1303      * as a formatting parameter to the LogRecord message property.
1304      * <p>
1305      * @param   level   One of the message level identifiers, e.g., SEVERE
1306      * @param   sourceClass    Name of the class that issued the logging request
1307      * @param   sourceMethod   Name of the method that issued the logging request
1308      * @param   bundle         Resource bundle to localize {@code msg},
1309      *                         can be {@code null}
1310      * @param   msg     The string message (or a key in the message catalog)
1311      * @param   thrown  Throwable associated with the log message.
1312      * @since 1.8
1313      */
1314     public void logrb(Level level, String sourceClass, String sourceMethod,
1315                       ResourceBundle bundle, String msg, Throwable thrown) {
1316         if (!isLoggable(level)) {
1317             return;
1318         }
1319         LogRecord lr = new LogRecord(level, msg);
1320         lr.setSourceClassName(sourceClass);
1321         lr.setSourceMethodName(sourceMethod);
1322         lr.setThrown(thrown);
1323         doLog(lr, bundle);
1324     }
1325 
1326     //======================================================================
1327     // Start of convenience methods for logging method entries and returns.
1328     //======================================================================
1329 
1330     /**
1331      * Log a method entry.
1332      * <p>
1333      * This is a convenience method that can be used to log entry
1334      * to a method.  A LogRecord with message "ENTRY", log level
1335      * FINER, and the given sourceMethod and sourceClass is logged.
1336      * <p>
1337      * @param   sourceClass    name of class that issued the logging request
1338      * @param   sourceMethod   name of method that is being entered
1339      */
1340     public void entering(String sourceClass, String sourceMethod) {
1341         logp(Level.FINER, sourceClass, sourceMethod, "ENTRY");
1342     }
1343 
1344     /**
1345      * Log a method entry, with one parameter.
1346      * <p>
1347      * This is a convenience method that can be used to log entry
1348      * to a method.  A LogRecord with message "ENTRY {0}", log level
1349      * FINER, and the given sourceMethod, sourceClass, and parameter
1350      * is logged.
1351      * <p>
1352      * @param   sourceClass    name of class that issued the logging request
1353      * @param   sourceMethod   name of method that is being entered
1354      * @param   param1         parameter to the method being entered
1355      */
1356     public void entering(String sourceClass, String sourceMethod, Object param1) {
1357         logp(Level.FINER, sourceClass, sourceMethod, "ENTRY {0}", param1);
1358     }
1359 
1360     /**
1361      * Log a method entry, with an array of parameters.
1362      * <p>
1363      * This is a convenience method that can be used to log entry
1364      * to a method.  A LogRecord with message "ENTRY" (followed by a
1365      * format {N} indicator for each entry in the parameter array),
1366      * log level FINER, and the given sourceMethod, sourceClass, and
1367      * parameters is logged.
1368      * <p>
1369      * @param   sourceClass    name of class that issued the logging request
1370      * @param   sourceMethod   name of method that is being entered
1371      * @param   params         array of parameters to the method being entered
1372      */
1373     public void entering(String sourceClass, String sourceMethod, Object params[]) {
1374         String msg = "ENTRY";
1375         if (params == null ) {
1376            logp(Level.FINER, sourceClass, sourceMethod, msg);
1377            return;
1378         }
1379         if (!isLoggable(Level.FINER)) return;
1380         for (int i = 0; i < params.length; i++) {
1381             msg = msg + " {" + i + "}";
1382         }
1383         logp(Level.FINER, sourceClass, sourceMethod, msg, params);
1384     }
1385 
1386     /**
1387      * Log a method return.
1388      * <p>
1389      * This is a convenience method that can be used to log returning
1390      * from a method.  A LogRecord with message "RETURN", log level
1391      * FINER, and the given sourceMethod and sourceClass is logged.
1392      * <p>
1393      * @param   sourceClass    name of class that issued the logging request
1394      * @param   sourceMethod   name of the method
1395      */
1396     public void exiting(String sourceClass, String sourceMethod) {
1397         logp(Level.FINER, sourceClass, sourceMethod, "RETURN");
1398     }
1399 
1400 
1401     /**
1402      * Log a method return, with result object.
1403      * <p>
1404      * This is a convenience method that can be used to log returning
1405      * from a method.  A LogRecord with message "RETURN {0}", log level
1406      * FINER, and the gives sourceMethod, sourceClass, and result
1407      * object is logged.
1408      * <p>
1409      * @param   sourceClass    name of class that issued the logging request
1410      * @param   sourceMethod   name of the method
1411      * @param   result  Object that is being returned
1412      */
1413     public void exiting(String sourceClass, String sourceMethod, Object result) {
1414         logp(Level.FINER, sourceClass, sourceMethod, "RETURN {0}", result);
1415     }
1416 
1417     /**
1418      * Log throwing an exception.
1419      * <p>
1420      * This is a convenience method to log that a method is
1421      * terminating by throwing an exception.  The logging is done
1422      * using the FINER level.
1423      * <p>
1424      * If the logger is currently enabled for the given message
1425      * level then the given arguments are stored in a LogRecord
1426      * which is forwarded to all registered output handlers.  The
1427      * LogRecord's message is set to "THROW".
1428      * <p>
1429      * Note that the thrown argument is stored in the LogRecord thrown
1430      * property, rather than the LogRecord parameters property.  Thus it is
1431      * processed specially by output Formatters and is not treated
1432      * as a formatting parameter to the LogRecord message property.
1433      * <p>
1434      * @param   sourceClass    name of class that issued the logging request
1435      * @param   sourceMethod  name of the method.
1436      * @param   thrown  The Throwable that is being thrown.
1437      */
1438     public void throwing(String sourceClass, String sourceMethod, Throwable thrown) {
1439         if (!isLoggable(Level.FINER)) {
1440             return;
1441         }
1442         LogRecord lr = new LogRecord(Level.FINER, "THROW");
1443         lr.setSourceClassName(sourceClass);
1444         lr.setSourceMethodName(sourceMethod);
1445         lr.setThrown(thrown);
1446         doLog(lr);
1447     }
1448 
1449     //=======================================================================
1450     // Start of simple convenience methods using level names as method names
1451     //=======================================================================
1452 
1453     /**
1454      * Log a SEVERE message.
1455      * <p>
1456      * If the logger is currently enabled for the SEVERE message
1457      * level then the given message is forwarded to all the
1458      * registered output Handler objects.
1459      * <p>
1460      * @param   msg     The string message (or a key in the message catalog)
1461      */
1462     public void severe(String msg) {
1463         log(Level.SEVERE, msg);
1464     }
1465 
1466     /**
1467      * Log a WARNING message.
1468      * <p>
1469      * If the logger is currently enabled for the WARNING message
1470      * level then the given message is forwarded to all the
1471      * registered output Handler objects.
1472      * <p>
1473      * @param   msg     The string message (or a key in the message catalog)
1474      */
1475     public void warning(String msg) {
1476         log(Level.WARNING, msg);
1477     }
1478 
1479     /**
1480      * Log an INFO message.
1481      * <p>
1482      * If the logger is currently enabled for the INFO message
1483      * level then the given message is forwarded to all the
1484      * registered output Handler objects.
1485      * <p>
1486      * @param   msg     The string message (or a key in the message catalog)
1487      */
1488     public void info(String msg) {
1489         log(Level.INFO, msg);
1490     }
1491 
1492     /**
1493      * Log a CONFIG message.
1494      * <p>
1495      * If the logger is currently enabled for the CONFIG message
1496      * level then the given message is forwarded to all the
1497      * registered output Handler objects.
1498      * <p>
1499      * @param   msg     The string message (or a key in the message catalog)
1500      */
1501     public void config(String msg) {
1502         log(Level.CONFIG, msg);
1503     }
1504 
1505     /**
1506      * Log a FINE message.
1507      * <p>
1508      * If the logger is currently enabled for the FINE message
1509      * level then the given message is forwarded to all the
1510      * registered output Handler objects.
1511      * <p>
1512      * @param   msg     The string message (or a key in the message catalog)
1513      */
1514     public void fine(String msg) {
1515         log(Level.FINE, msg);
1516     }
1517 
1518     /**
1519      * Log a FINER message.
1520      * <p>
1521      * If the logger is currently enabled for the FINER message
1522      * level then the given message is forwarded to all the
1523      * registered output Handler objects.
1524      * <p>
1525      * @param   msg     The string message (or a key in the message catalog)
1526      */
1527     public void finer(String msg) {
1528         log(Level.FINER, msg);
1529     }
1530 
1531     /**
1532      * Log a FINEST message.
1533      * <p>
1534      * If the logger is currently enabled for the FINEST message
1535      * level then the given message is forwarded to all the
1536      * registered output Handler objects.
1537      * <p>
1538      * @param   msg     The string message (or a key in the message catalog)
1539      */
1540     public void finest(String msg) {
1541         log(Level.FINEST, msg);
1542     }
1543 
1544     //=======================================================================
1545     // Start of simple convenience methods using level names as method names
1546     // and use Supplier<String>
1547     //=======================================================================
1548 
1549     /**
1550      * Log a SEVERE message, which is only to be constructed if the logging
1551      * level is such that the message will actually be logged.
1552      * <p>
1553      * If the logger is currently enabled for the SEVERE message
1554      * level then the message is constructed by invoking the provided
1555      * supplier function and forwarded to all the registered output
1556      * Handler objects.
1557      * <p>
1558      * @param   msgSupplier   A function, which when called, produces the
1559      *                        desired log message
1560      * @since   1.8
1561      */
1562     public void severe(Supplier<String> msgSupplier) {
1563         log(Level.SEVERE, msgSupplier);
1564     }
1565 
1566     /**
1567      * Log a WARNING message, which is only to be constructed if the logging
1568      * level is such that the message will actually be logged.
1569      * <p>
1570      * If the logger is currently enabled for the WARNING message
1571      * level then the message is constructed by invoking the provided
1572      * supplier function and forwarded to all the registered output
1573      * Handler objects.
1574      * <p>
1575      * @param   msgSupplier   A function, which when called, produces the
1576      *                        desired log message
1577      * @since   1.8
1578      */
1579     public void warning(Supplier<String> msgSupplier) {
1580         log(Level.WARNING, msgSupplier);
1581     }
1582 
1583     /**
1584      * Log a INFO message, which is only to be constructed if the logging
1585      * level is such that the message will actually be logged.
1586      * <p>
1587      * If the logger is currently enabled for the INFO message
1588      * level then the message is constructed by invoking the provided
1589      * supplier function and forwarded to all the registered output
1590      * Handler objects.
1591      * <p>
1592      * @param   msgSupplier   A function, which when called, produces the
1593      *                        desired log message
1594      * @since   1.8
1595      */
1596     public void info(Supplier<String> msgSupplier) {
1597         log(Level.INFO, msgSupplier);
1598     }
1599 
1600     /**
1601      * Log a CONFIG message, which is only to be constructed if the logging
1602      * level is such that the message will actually be logged.
1603      * <p>
1604      * If the logger is currently enabled for the CONFIG message
1605      * level then the message is constructed by invoking the provided
1606      * supplier function and forwarded to all the registered output
1607      * Handler objects.
1608      * <p>
1609      * @param   msgSupplier   A function, which when called, produces the
1610      *                        desired log message
1611      * @since   1.8
1612      */
1613     public void config(Supplier<String> msgSupplier) {
1614         log(Level.CONFIG, msgSupplier);
1615     }
1616 
1617     /**
1618      * Log a FINE message, which is only to be constructed if the logging
1619      * level is such that the message will actually be logged.
1620      * <p>
1621      * If the logger is currently enabled for the FINE message
1622      * level then the message is constructed by invoking the provided
1623      * supplier function and forwarded to all the registered output
1624      * Handler objects.
1625      * <p>
1626      * @param   msgSupplier   A function, which when called, produces the
1627      *                        desired log message
1628      * @since   1.8
1629      */
1630     public void fine(Supplier<String> msgSupplier) {
1631         log(Level.FINE, msgSupplier);
1632     }
1633 
1634     /**
1635      * Log a FINER message, which is only to be constructed if the logging
1636      * level is such that the message will actually be logged.
1637      * <p>
1638      * If the logger is currently enabled for the FINER message
1639      * level then the message is constructed by invoking the provided
1640      * supplier function and forwarded to all the registered output
1641      * Handler objects.
1642      * <p>
1643      * @param   msgSupplier   A function, which when called, produces the
1644      *                        desired log message
1645      * @since   1.8
1646      */
1647     public void finer(Supplier<String> msgSupplier) {
1648         log(Level.FINER, msgSupplier);
1649     }
1650 
1651     /**
1652      * Log a FINEST message, which is only to be constructed if the logging
1653      * level is such that the message will actually be logged.
1654      * <p>
1655      * If the logger is currently enabled for the FINEST message
1656      * level then the message is constructed by invoking the provided
1657      * supplier function and forwarded to all the registered output
1658      * Handler objects.
1659      * <p>
1660      * @param   msgSupplier   A function, which when called, produces the
1661      *                        desired log message
1662      * @since   1.8
1663      */
1664     public void finest(Supplier<String> msgSupplier) {
1665         log(Level.FINEST, msgSupplier);
1666     }
1667 
1668     //================================================================
1669     // End of convenience methods
1670     //================================================================
1671 
1672     /**
1673      * Set the log level specifying which message levels will be
1674      * logged by this logger.  Message levels lower than this
1675      * value will be discarded.  The level value Level.OFF
1676      * can be used to turn off logging.
1677      * <p>
1678      * If the new level is null, it means that this node should
1679      * inherit its level from its nearest ancestor with a specific


1752     /**
1753      * Remove a log Handler.
1754      * <P>
1755      * Returns silently if the given Handler is not found or is null
1756      *
1757      * @param   handler a logging Handler
1758      * @throws  SecurityException if a security manager exists,
1759      *          this logger is not anonymous, and the caller
1760      *          does not have LoggingPermission("control").
1761      */
1762     public void removeHandler(Handler handler) throws SecurityException {
1763         checkPermission();
1764         if (handler == null) {
1765             return;
1766         }
1767         handlers.remove(handler);
1768     }
1769 
1770     /**
1771      * Get the Handlers associated with this logger.
1772      * <p>
1773      * @return  an array of all registered Handlers
1774      */
1775     public Handler[] getHandlers() {
1776         return accessCheckedHandlers();
1777     }
1778 
1779     // This method should ideally be marked final - but unfortunately
1780     // it needs to be overridden by LogManager.RootLogger
1781     Handler[] accessCheckedHandlers() {
1782         return handlers.toArray(emptyHandlers);
1783     }
1784 
1785     /**
1786      * Specify whether or not this logger should send its output
1787      * to its parent Logger.  This means that any LogRecords will
1788      * also be written to the parent's Handlers, and potentially
1789      * to its parent, recursively up the namespace.
1790      *
1791      * @param useParentHandlers   true if output is to be sent to the
1792      *          logger's parent.


1998      * <p>
1999      * The result will be null if it is called on the root Logger
2000      * in the namespace.
2001      *
2002      * @return nearest existing parent Logger
2003      */
2004     public Logger getParent() {
2005         // Note: this used to be synchronized on treeLock.  However, this only
2006         // provided memory semantics, as there was no guarantee that the caller
2007         // would synchronize on treeLock (in fact, there is no way for external
2008         // callers to so synchronize).  Therefore, we have made parent volatile
2009         // instead.
2010         return parent;
2011     }
2012 
2013     /**
2014      * Set the parent for this Logger.  This method is used by
2015      * the LogManager to update a Logger when the namespace changes.
2016      * <p>
2017      * It should not be called from application code.
2018      * <p>
2019      * @param  parent   the new parent logger
2020      * @throws  SecurityException  if a security manager exists and if
2021      *          the caller does not have LoggingPermission("control").
2022      */
2023     public void setParent(Logger parent) {
2024         if (parent == null) {
2025             throw new NullPointerException();
2026         }
2027 
2028         // check permission for all loggers, including anonymous loggers
2029         if (manager == null) {
2030             manager = LogManager.getLogManager();
2031         }
2032         manager.checkPermission();
2033 
2034         doSetParent(parent);
2035     }
2036 
2037     // Private method to do the work for parenting a child
2038     // Logger onto a parent logger.




 321         LogManager.getLogManager();
 322 
 323         // Now the global LogManager should be initialized,
 324         // and the global logger should have been added to
 325         // it, unless we were called within the constructor of a LogManager
 326         // subclass installed as LogManager, in which case global.manager
 327         // would still be null, and global will be lazily initialized later on.
 328 
 329         return global;
 330     }
 331 
 332     /**
 333      * The "global" Logger object is provided as a convenience to developers
 334      * who are making casual use of the Logging package.  Developers
 335      * who are making serious use of the logging package (for example
 336      * in products) should create and use their own Logger objects,
 337      * with appropriate names, so that logging can be controlled on a
 338      * suitable per-Logger granularity. Developers also need to keep a
 339      * strong reference to their Logger objects to prevent them from
 340      * being garbage collected.
 341      *
 342      * @deprecated Initialization of this field is prone to deadlocks.
 343      * The field must be initialized by the Logger class initialization
 344      * which may cause deadlocks with the LogManager class initialization.
 345      * In such cases two class initialization wait for each other to complete.
 346      * The preferred way to get the global logger object is via the call
 347      * <code>Logger.getGlobal()</code>.
 348      * For compatibility with old JDK versions where the
 349      * <code>Logger.getGlobal()</code> is not available use the call
 350      * <code>Logger.getLogger(Logger.GLOBAL_LOGGER_NAME)</code>
 351      * or <code>Logger.getLogger("global")</code>.
 352      */
 353     @Deprecated
 354     public static final Logger global = new Logger(GLOBAL_LOGGER_NAME);
 355 
 356     /**
 357      * Protected method to construct a logger for a named subsystem.
 358      * <p>
 359      * The logger will be initially configured with a null Level
 360      * and with useParentHandlers set to true.
 361      *


 509      * <p>
 510      * If a new logger is created its log level will be configured
 511      * based on the LogManager and it will configured to also send logging
 512      * output to its parent's Handlers.  It will be registered in
 513      * the LogManager global namespace.
 514      * <p>
 515      * Note: The LogManager may only retain a weak reference to the newly
 516      * created Logger. It is important to understand that a previously
 517      * created Logger with the given name may be garbage collected at any
 518      * time if there is no strong reference to the Logger. In particular,
 519      * this means that two back-to-back calls like
 520      * {@code getLogger("MyLogger", ...).log(...)} may use different Logger
 521      * objects named "MyLogger" if there is no strong reference to the
 522      * Logger named "MyLogger" elsewhere in the program.
 523      * <p>
 524      * If the named Logger already exists and does not yet have a
 525      * localization resource bundle then the given resource bundle
 526      * name is used.  If the named Logger already exists and has
 527      * a different resource bundle name then an IllegalArgumentException
 528      * is thrown.
 529      *
 530      * @param   name    A name for the logger.  This should
 531      *                          be a dot-separated name and should normally
 532      *                          be based on the package name or class name
 533      *                          of the subsystem, such as java.net
 534      *                          or javax.swing
 535      * @param   resourceBundleName  name of ResourceBundle to be used for localizing
 536      *                          messages for this logger. May be {@code null}
 537      *                          if none of the messages require localization.
 538      * @return a suitable Logger
 539      * @throws MissingResourceException if the resourceBundleName is non-null and
 540      *             no corresponding resource can be found.
 541      * @throws IllegalArgumentException if the Logger already exists and uses
 542      *             a different resource bundle name; or if
 543      *             {@code resourceBundleName} is {@code null} but the named
 544      *             logger has a resource bundle set.
 545      * @throws NullPointerException if the name is null.
 546      */
 547 
 548     // Synchronization is not required here. All synchronization for
 549     // adding a new Logger object is handled by LogManager.addLogger().


 578     }
 579 
 580     /**
 581      * Create an anonymous Logger.  The newly created Logger is not
 582      * registered in the LogManager namespace.  There will be no
 583      * access checks on updates to the logger.
 584      * <p>
 585      * This factory method is primarily intended for use from applets.
 586      * Because the resulting Logger is anonymous it can be kept private
 587      * by the creating class.  This removes the need for normal security
 588      * checks, which in turn allows untrusted applet code to update
 589      * the control state of the Logger.  For example an applet can do
 590      * a setLevel or an addHandler on an anonymous Logger.
 591      * <p>
 592      * Even although the new logger is anonymous, it is configured
 593      * to have the root logger ("") as its parent.  This means that
 594      * by default it inherits its effective level and handlers
 595      * from the root logger. Changing its parent via the
 596      * {@link #setParent(java.util.logging.Logger) setParent} method
 597      * will still require the security permission specified by that method.

 598      *
 599      * @return a newly created private Logger
 600      */
 601     public static Logger getAnonymousLogger() {
 602         return getAnonymousLogger(null);
 603     }
 604 
 605     /**
 606      * Create an anonymous Logger.  The newly created Logger is not
 607      * registered in the LogManager namespace.  There will be no
 608      * access checks on updates to the logger.
 609      * <p>
 610      * This factory method is primarily intended for use from applets.
 611      * Because the resulting Logger is anonymous it can be kept private
 612      * by the creating class.  This removes the need for normal security
 613      * checks, which in turn allows untrusted applet code to update
 614      * the control state of the Logger.  For example an applet can do
 615      * a setLevel or an addHandler on an anonymous Logger.
 616      * <p>
 617      * Even although the new logger is anonymous, it is configured
 618      * to have the root logger ("") as its parent.  This means that
 619      * by default it inherits its effective level and handlers
 620      * from the root logger.  Changing its parent via the
 621      * {@link #setParent(java.util.logging.Logger) setParent} method
 622      * will still require the security permission specified by that method.
 623      *
 624      * @param   resourceBundleName  name of ResourceBundle to be used for localizing
 625      *                          messages for this logger.
 626      *          May be null if none of the messages require localization.
 627      * @return a newly created private Logger
 628      * @throws MissingResourceException if the resourceBundleName is non-null and
 629      *             no corresponding resource can be found.
 630      */
 631 
 632     // Synchronization is not required here. All synchronization for
 633     // adding a new anonymous Logger object is handled by doSetParent().
 634     @CallerSensitive
 635     public static Logger getAnonymousLogger(String resourceBundleName) {
 636         LogManager manager = LogManager.getLogManager();
 637         // cleanup some Loggers that have been GC'ed
 638         manager.drainLoggerRefQueueBounded();
 639         Logger result = new Logger(null, resourceBundleName,
 640                                    Reflection.getCallerClass(), manager, false);
 641         result.anonymous = true;
 642         Logger root = manager.getLogger("");
 643         result.doSetParent(root);


 758         final ResourceBundle  bundle = lb.userBundle;
 759         final String ebname = lb.resourceBundleName;
 760         if (ebname != null && bundle != null) {
 761             lr.setResourceBundleName(ebname);
 762             lr.setResourceBundle(bundle);
 763         }
 764         log(lr);
 765     }
 766 
 767 
 768     //================================================================
 769     // Start of convenience methods WITHOUT className and methodName
 770     //================================================================
 771 
 772     /**
 773      * Log a message, with no arguments.
 774      * <p>
 775      * If the logger is currently enabled for the given message
 776      * level then the given message is forwarded to all the
 777      * registered output Handler objects.
 778      *
 779      * @param   level   One of the message level identifiers, e.g., SEVERE
 780      * @param   msg     The string message (or a key in the message catalog)
 781      */
 782     public void log(Level level, String msg) {
 783         if (!isLoggable(level)) {
 784             return;
 785         }
 786         LogRecord lr = new LogRecord(level, msg);
 787         doLog(lr);
 788     }
 789 
 790     /**
 791      * Log a message, which is only to be constructed if the logging level
 792      * is such that the message will actually be logged.
 793      * <p>
 794      * If the logger is currently enabled for the given message
 795      * level then the message is constructed by invoking the provided
 796      * supplier function and forwarded to all the registered output
 797      * Handler objects.
 798      *
 799      * @param   level   One of the message level identifiers, e.g., SEVERE
 800      * @param   msgSupplier   A function, which when called, produces the
 801      *                        desired log message
 802      */
 803     public void log(Level level, Supplier<String> msgSupplier) {
 804         if (!isLoggable(level)) {
 805             return;
 806         }
 807         LogRecord lr = new LogRecord(level, msgSupplier.get());
 808         doLog(lr);
 809     }
 810 
 811     /**
 812      * Log a message, with one object parameter.
 813      * <p>
 814      * If the logger is currently enabled for the given message
 815      * level then a corresponding LogRecord is created and forwarded
 816      * to all the registered output Handler objects.
 817      *
 818      * @param   level   One of the message level identifiers, e.g., SEVERE
 819      * @param   msg     The string message (or a key in the message catalog)
 820      * @param   param1  parameter to the message
 821      */
 822     public void log(Level level, String msg, Object param1) {
 823         if (!isLoggable(level)) {
 824             return;
 825         }
 826         LogRecord lr = new LogRecord(level, msg);
 827         Object params[] = { param1 };
 828         lr.setParameters(params);
 829         doLog(lr);
 830     }
 831 
 832     /**
 833      * Log a message, with an array of object arguments.
 834      * <p>
 835      * If the logger is currently enabled for the given message
 836      * level then a corresponding LogRecord is created and forwarded
 837      * to all the registered output Handler objects.
 838      *
 839      * @param   level   One of the message level identifiers, e.g., SEVERE
 840      * @param   msg     The string message (or a key in the message catalog)
 841      * @param   params  array of parameters to the message
 842      */
 843     public void log(Level level, String msg, Object params[]) {
 844         if (!isLoggable(level)) {
 845             return;
 846         }
 847         LogRecord lr = new LogRecord(level, msg);
 848         lr.setParameters(params);
 849         doLog(lr);
 850     }
 851 
 852     /**
 853      * Log a message, with associated Throwable information.
 854      * <p>
 855      * If the logger is currently enabled for the given message
 856      * level then the given arguments are stored in a LogRecord
 857      * which is forwarded to all registered output handlers.
 858      * <p>
 859      * Note that the thrown argument is stored in the LogRecord thrown
 860      * property, rather than the LogRecord parameters property.  Thus it is
 861      * processed specially by output Formatters and is not treated
 862      * as a formatting parameter to the LogRecord message property.
 863      *
 864      * @param   level   One of the message level identifiers, e.g., SEVERE
 865      * @param   msg     The string message (or a key in the message catalog)
 866      * @param   thrown  Throwable associated with log message.
 867      */
 868     public void log(Level level, String msg, Throwable thrown) {
 869         if (!isLoggable(level)) {
 870             return;
 871         }
 872         LogRecord lr = new LogRecord(level, msg);
 873         lr.setThrown(thrown);
 874         doLog(lr);
 875     }
 876 
 877     /**
 878      * Log a lazily constructed message, with associated Throwable information.
 879      * <p>
 880      * If the logger is currently enabled for the given message level then the
 881      * message is constructed by invoking the provided supplier function. The
 882      * message and the given {@link Throwable} are then stored in a {@link
 883      * LogRecord} which is forwarded to all registered output handlers.
 884      * <p>
 885      * Note that the thrown argument is stored in the LogRecord thrown
 886      * property, rather than the LogRecord parameters property.  Thus it is
 887      * processed specially by output Formatters and is not treated
 888      * as a formatting parameter to the LogRecord message property.
 889      *
 890      * @param   level   One of the message level identifiers, e.g., SEVERE
 891      * @param   thrown  Throwable associated with log message.
 892      * @param   msgSupplier   A function, which when called, produces the
 893      *                        desired log message
 894      * @since   1.8
 895      */
 896     public void log(Level level, Throwable thrown, Supplier<String> msgSupplier) {
 897         if (!isLoggable(level)) {
 898             return;
 899         }
 900         LogRecord lr = new LogRecord(level, msgSupplier.get());
 901         lr.setThrown(thrown);
 902         doLog(lr);
 903     }
 904 
 905     //================================================================
 906     // Start of convenience methods WITH className and methodName
 907     //================================================================
 908 
 909     /**
 910      * Log a message, specifying source class and method,
 911      * with no arguments.
 912      * <p>
 913      * If the logger is currently enabled for the given message
 914      * level then the given message is forwarded to all the
 915      * registered output Handler objects.
 916      *
 917      * @param   level   One of the message level identifiers, e.g., SEVERE
 918      * @param   sourceClass    name of class that issued the logging request
 919      * @param   sourceMethod   name of method that issued the logging request
 920      * @param   msg     The string message (or a key in the message catalog)
 921      */
 922     public void logp(Level level, String sourceClass, String sourceMethod, String msg) {
 923         if (!isLoggable(level)) {
 924             return;
 925         }
 926         LogRecord lr = new LogRecord(level, msg);
 927         lr.setSourceClassName(sourceClass);
 928         lr.setSourceMethodName(sourceMethod);
 929         doLog(lr);
 930     }
 931 
 932     /**
 933      * Log a lazily constructed message, specifying source class and method,
 934      * with no arguments.
 935      * <p>
 936      * If the logger is currently enabled for the given message
 937      * level then the message is constructed by invoking the provided
 938      * supplier function and forwarded to all the registered output
 939      * Handler objects.
 940      *
 941      * @param   level   One of the message level identifiers, e.g., SEVERE
 942      * @param   sourceClass    name of class that issued the logging request
 943      * @param   sourceMethod   name of method that issued the logging request
 944      * @param   msgSupplier   A function, which when called, produces the
 945      *                        desired log message
 946      * @since   1.8
 947      */
 948     public void logp(Level level, String sourceClass, String sourceMethod,
 949                      Supplier<String> msgSupplier) {
 950         if (!isLoggable(level)) {
 951             return;
 952         }
 953         LogRecord lr = new LogRecord(level, msgSupplier.get());
 954         lr.setSourceClassName(sourceClass);
 955         lr.setSourceMethodName(sourceMethod);
 956         doLog(lr);
 957     }
 958 
 959     /**
 960      * Log a message, specifying source class and method,
 961      * with a single object parameter to the log message.
 962      * <p>
 963      * If the logger is currently enabled for the given message
 964      * level then a corresponding LogRecord is created and forwarded
 965      * to all the registered output Handler objects.
 966      *
 967      * @param   level   One of the message level identifiers, e.g., SEVERE
 968      * @param   sourceClass    name of class that issued the logging request
 969      * @param   sourceMethod   name of method that issued the logging request
 970      * @param   msg      The string message (or a key in the message catalog)
 971      * @param   param1    Parameter to the log message.
 972      */
 973     public void logp(Level level, String sourceClass, String sourceMethod,
 974                                                 String msg, Object param1) {
 975         if (!isLoggable(level)) {
 976             return;
 977         }
 978         LogRecord lr = new LogRecord(level, msg);
 979         lr.setSourceClassName(sourceClass);
 980         lr.setSourceMethodName(sourceMethod);
 981         Object params[] = { param1 };
 982         lr.setParameters(params);
 983         doLog(lr);
 984     }
 985 
 986     /**
 987      * Log a message, specifying source class and method,
 988      * with an array of object arguments.
 989      * <p>
 990      * If the logger is currently enabled for the given message
 991      * level then a corresponding LogRecord is created and forwarded
 992      * to all the registered output Handler objects.
 993      *
 994      * @param   level   One of the message level identifiers, e.g., SEVERE
 995      * @param   sourceClass    name of class that issued the logging request
 996      * @param   sourceMethod   name of method that issued the logging request
 997      * @param   msg     The string message (or a key in the message catalog)
 998      * @param   params  Array of parameters to the message
 999      */
1000     public void logp(Level level, String sourceClass, String sourceMethod,
1001                                                 String msg, Object params[]) {
1002         if (!isLoggable(level)) {
1003             return;
1004         }
1005         LogRecord lr = new LogRecord(level, msg);
1006         lr.setSourceClassName(sourceClass);
1007         lr.setSourceMethodName(sourceMethod);
1008         lr.setParameters(params);
1009         doLog(lr);
1010     }
1011 
1012     /**
1013      * Log a message, specifying source class and method,
1014      * with associated Throwable information.
1015      * <p>
1016      * If the logger is currently enabled for the given message
1017      * level then the given arguments are stored in a LogRecord
1018      * which is forwarded to all registered output handlers.
1019      * <p>
1020      * Note that the thrown argument is stored in the LogRecord thrown
1021      * property, rather than the LogRecord parameters property.  Thus it is
1022      * processed specially by output Formatters and is not treated
1023      * as a formatting parameter to the LogRecord message property.
1024      *
1025      * @param   level   One of the message level identifiers, e.g., SEVERE
1026      * @param   sourceClass    name of class that issued the logging request
1027      * @param   sourceMethod   name of method that issued the logging request
1028      * @param   msg     The string message (or a key in the message catalog)
1029      * @param   thrown  Throwable associated with log message.
1030      */
1031     public void logp(Level level, String sourceClass, String sourceMethod,
1032                      String msg, Throwable thrown) {
1033         if (!isLoggable(level)) {
1034             return;
1035         }
1036         LogRecord lr = new LogRecord(level, msg);
1037         lr.setSourceClassName(sourceClass);
1038         lr.setSourceMethodName(sourceMethod);
1039         lr.setThrown(thrown);
1040         doLog(lr);
1041     }
1042 
1043     /**
1044      * Log a lazily constructed message, specifying source class and method,
1045      * with associated Throwable information.
1046      * <p>
1047      * If the logger is currently enabled for the given message level then the
1048      * message is constructed by invoking the provided supplier function. The
1049      * message and the given {@link Throwable} are then stored in a {@link
1050      * LogRecord} which is forwarded to all registered output handlers.
1051      * <p>
1052      * Note that the thrown argument is stored in the LogRecord thrown
1053      * property, rather than the LogRecord parameters property.  Thus it is
1054      * processed specially by output Formatters and is not treated
1055      * as a formatting parameter to the LogRecord message property.
1056      *
1057      * @param   level   One of the message level identifiers, e.g., SEVERE
1058      * @param   sourceClass    name of class that issued the logging request
1059      * @param   sourceMethod   name of method that issued the logging request
1060      * @param   thrown  Throwable associated with log message.
1061      * @param   msgSupplier   A function, which when called, produces the
1062      *                        desired log message
1063      * @since   1.8
1064      */
1065     public void logp(Level level, String sourceClass, String sourceMethod,
1066                      Throwable thrown, Supplier<String> msgSupplier) {
1067         if (!isLoggable(level)) {
1068             return;
1069         }
1070         LogRecord lr = new LogRecord(level, msgSupplier.get());
1071         lr.setSourceClassName(sourceClass);
1072         lr.setSourceMethodName(sourceMethod);
1073         lr.setThrown(thrown);
1074         doLog(lr);
1075     }
1076 


1095     private void doLog(LogRecord lr, ResourceBundle rb) {
1096         lr.setLoggerName(name);
1097         if (rb != null) {
1098             lr.setResourceBundleName(rb.getBaseBundleName());
1099             lr.setResourceBundle(rb);
1100         }
1101         log(lr);
1102     }
1103 
1104     /**
1105      * Log a message, specifying source class, method, and resource bundle name
1106      * with no arguments.
1107      * <p>
1108      * If the logger is currently enabled for the given message
1109      * level then the given message is forwarded to all the
1110      * registered output Handler objects.
1111      * <p>
1112      * The msg string is localized using the named resource bundle.  If the
1113      * resource bundle name is null, or an empty String or invalid
1114      * then the msg string is not localized.
1115      *
1116      * @param   level   One of the message level identifiers, e.g., SEVERE
1117      * @param   sourceClass    name of class that issued the logging request
1118      * @param   sourceMethod   name of method that issued the logging request
1119      * @param   bundleName     name of resource bundle to localize msg,
1120      *                         can be null
1121      * @param   msg     The string message (or a key in the message catalog)
1122      * @deprecated Use {@link #logrb(java.util.logging.Level, java.lang.String,
1123      * java.lang.String, java.util.ResourceBundle, java.lang.String,
1124      * java.lang.Object...)} instead.
1125      */
1126     @Deprecated
1127     public void logrb(Level level, String sourceClass, String sourceMethod,
1128                                 String bundleName, String msg) {
1129         if (!isLoggable(level)) {
1130             return;
1131         }
1132         LogRecord lr = new LogRecord(level, msg);
1133         lr.setSourceClassName(sourceClass);
1134         lr.setSourceMethodName(sourceMethod);
1135         doLog(lr, bundleName);
1136     }
1137 
1138     /**
1139      * Log a message, specifying source class, method, and resource bundle name,
1140      * with a single object parameter to the log message.
1141      * <p>
1142      * If the logger is currently enabled for the given message
1143      * level then a corresponding LogRecord is created and forwarded
1144      * to all the registered output Handler objects.
1145      * <p>
1146      * The msg string is localized using the named resource bundle.  If the
1147      * resource bundle name is null, or an empty String or invalid
1148      * then the msg string is not localized.
1149      *
1150      * @param   level   One of the message level identifiers, e.g., SEVERE
1151      * @param   sourceClass    name of class that issued the logging request
1152      * @param   sourceMethod   name of method that issued the logging request
1153      * @param   bundleName     name of resource bundle to localize msg,
1154      *                         can be null
1155      * @param   msg      The string message (or a key in the message catalog)
1156      * @param   param1    Parameter to the log message.
1157      * @deprecated Use {@link #logrb(java.util.logging.Level, java.lang.String,
1158      *   java.lang.String, java.util.ResourceBundle, java.lang.String,
1159      *   java.lang.Object...)} instead
1160      */
1161     @Deprecated
1162     public void logrb(Level level, String sourceClass, String sourceMethod,
1163                                 String bundleName, String msg, Object param1) {
1164         if (!isLoggable(level)) {
1165             return;
1166         }
1167         LogRecord lr = new LogRecord(level, msg);
1168         lr.setSourceClassName(sourceClass);
1169         lr.setSourceMethodName(sourceMethod);
1170         Object params[] = { param1 };
1171         lr.setParameters(params);
1172         doLog(lr, bundleName);
1173     }
1174 
1175     /**
1176      * Log a message, specifying source class, method, and resource bundle name,
1177      * with an array of object arguments.
1178      * <p>
1179      * If the logger is currently enabled for the given message
1180      * level then a corresponding LogRecord is created and forwarded
1181      * to all the registered output Handler objects.
1182      * <p>
1183      * The msg string is localized using the named resource bundle.  If the
1184      * resource bundle name is null, or an empty String or invalid
1185      * then the msg string is not localized.
1186      *
1187      * @param   level   One of the message level identifiers, e.g., SEVERE
1188      * @param   sourceClass    name of class that issued the logging request
1189      * @param   sourceMethod   name of method that issued the logging request
1190      * @param   bundleName     name of resource bundle to localize msg,
1191      *                         can be null.
1192      * @param   msg     The string message (or a key in the message catalog)
1193      * @param   params  Array of parameters to the message
1194      * @deprecated Use {@link #logrb(java.util.logging.Level, java.lang.String,
1195      *      java.lang.String, java.util.ResourceBundle, java.lang.String,
1196      *      java.lang.Object...)} instead.
1197      */
1198     @Deprecated
1199     public void logrb(Level level, String sourceClass, String sourceMethod,
1200                                 String bundleName, String msg, Object params[]) {
1201         if (!isLoggable(level)) {
1202             return;
1203         }
1204         LogRecord lr = new LogRecord(level, msg);
1205         lr.setSourceClassName(sourceClass);
1206         lr.setSourceMethodName(sourceMethod);
1207         lr.setParameters(params);
1208         doLog(lr, bundleName);
1209     }
1210 
1211     /**
1212      * Log a message, specifying source class, method, and resource bundle,
1213      * with an optional list of message parameters.
1214      * <p>
1215      * If the logger is currently enabled for the given message
1216      * level then a corresponding LogRecord is created and forwarded
1217      * to all the registered output Handler objects.
1218      * <p>
1219      * The {@code msg} string is localized using the given resource bundle.
1220      * If the resource bundle is {@code null}, then the {@code msg} string is not
1221      * localized.
1222      *
1223      * @param   level   One of the message level identifiers, e.g., SEVERE
1224      * @param   sourceClass    Name of the class that issued the logging request
1225      * @param   sourceMethod   Name of the method that issued the logging request
1226      * @param   bundle         Resource bundle to localize {@code msg},
1227      *                         can be {@code null}.
1228      * @param   msg     The string message (or a key in the message catalog)
1229      * @param   params  Parameters to the message (optional, may be none).
1230      * @since 1.8
1231      */
1232     public void logrb(Level level, String sourceClass, String sourceMethod,
1233                       ResourceBundle bundle, String msg, Object... params) {
1234         if (!isLoggable(level)) {
1235             return;
1236         }
1237         LogRecord lr = new LogRecord(level, msg);
1238         lr.setSourceClassName(sourceClass);
1239         lr.setSourceMethodName(sourceMethod);
1240         if (params != null && params.length != 0) {
1241             lr.setParameters(params);
1242         }
1243         doLog(lr, bundle);
1244     }
1245 
1246     /**
1247      * Log a message, specifying source class, method, and resource bundle name,
1248      * with associated Throwable information.
1249      * <p>
1250      * If the logger is currently enabled for the given message
1251      * level then the given arguments are stored in a LogRecord
1252      * which is forwarded to all registered output handlers.
1253      * <p>
1254      * The msg string is localized using the named resource bundle.  If the
1255      * resource bundle name is null, or an empty String or invalid
1256      * then the msg string is not localized.
1257      * <p>
1258      * Note that the thrown argument is stored in the LogRecord thrown
1259      * property, rather than the LogRecord parameters property.  Thus it is
1260      * processed specially by output Formatters and is not treated
1261      * as a formatting parameter to the LogRecord message property.
1262      *
1263      * @param   level   One of the message level identifiers, e.g., SEVERE
1264      * @param   sourceClass    name of class that issued the logging request
1265      * @param   sourceMethod   name of method that issued the logging request
1266      * @param   bundleName     name of resource bundle to localize msg,
1267      *                         can be null
1268      * @param   msg     The string message (or a key in the message catalog)
1269      * @param   thrown  Throwable associated with log message.
1270      * @deprecated Use {@link #logrb(java.util.logging.Level, java.lang.String,
1271      *     java.lang.String, java.util.ResourceBundle, java.lang.String,
1272      *     java.lang.Throwable)} instead.
1273      */
1274     @Deprecated
1275     public void logrb(Level level, String sourceClass, String sourceMethod,
1276                                         String bundleName, String msg, Throwable thrown) {
1277         if (!isLoggable(level)) {
1278             return;
1279         }
1280         LogRecord lr = new LogRecord(level, msg);
1281         lr.setSourceClassName(sourceClass);
1282         lr.setSourceMethodName(sourceMethod);
1283         lr.setThrown(thrown);
1284         doLog(lr, bundleName);
1285     }
1286 
1287     /**
1288      * Log a message, specifying source class, method, and resource bundle,
1289      * with associated Throwable information.
1290      * <p>
1291      * If the logger is currently enabled for the given message
1292      * level then the given arguments are stored in a LogRecord
1293      * which is forwarded to all registered output handlers.
1294      * <p>
1295      * The {@code msg} string is localized using the given resource bundle.
1296      * If the resource bundle is {@code null}, then the {@code msg} string is not
1297      * localized.
1298      * <p>
1299      * Note that the thrown argument is stored in the LogRecord thrown
1300      * property, rather than the LogRecord parameters property.  Thus it is
1301      * processed specially by output Formatters and is not treated
1302      * as a formatting parameter to the LogRecord message property.
1303      *
1304      * @param   level   One of the message level identifiers, e.g., SEVERE
1305      * @param   sourceClass    Name of the class that issued the logging request
1306      * @param   sourceMethod   Name of the method that issued the logging request
1307      * @param   bundle         Resource bundle to localize {@code msg},
1308      *                         can be {@code null}
1309      * @param   msg     The string message (or a key in the message catalog)
1310      * @param   thrown  Throwable associated with the log message.
1311      * @since 1.8
1312      */
1313     public void logrb(Level level, String sourceClass, String sourceMethod,
1314                       ResourceBundle bundle, String msg, Throwable thrown) {
1315         if (!isLoggable(level)) {
1316             return;
1317         }
1318         LogRecord lr = new LogRecord(level, msg);
1319         lr.setSourceClassName(sourceClass);
1320         lr.setSourceMethodName(sourceMethod);
1321         lr.setThrown(thrown);
1322         doLog(lr, bundle);
1323     }
1324 
1325     //======================================================================
1326     // Start of convenience methods for logging method entries and returns.
1327     //======================================================================
1328 
1329     /**
1330      * Log a method entry.
1331      * <p>
1332      * This is a convenience method that can be used to log entry
1333      * to a method.  A LogRecord with message "ENTRY", log level
1334      * FINER, and the given sourceMethod and sourceClass is logged.
1335      *
1336      * @param   sourceClass    name of class that issued the logging request
1337      * @param   sourceMethod   name of method that is being entered
1338      */
1339     public void entering(String sourceClass, String sourceMethod) {
1340         logp(Level.FINER, sourceClass, sourceMethod, "ENTRY");
1341     }
1342 
1343     /**
1344      * Log a method entry, with one parameter.
1345      * <p>
1346      * This is a convenience method that can be used to log entry
1347      * to a method.  A LogRecord with message "ENTRY {0}", log level
1348      * FINER, and the given sourceMethod, sourceClass, and parameter
1349      * is logged.
1350      *
1351      * @param   sourceClass    name of class that issued the logging request
1352      * @param   sourceMethod   name of method that is being entered
1353      * @param   param1         parameter to the method being entered
1354      */
1355     public void entering(String sourceClass, String sourceMethod, Object param1) {
1356         logp(Level.FINER, sourceClass, sourceMethod, "ENTRY {0}", param1);
1357     }
1358 
1359     /**
1360      * Log a method entry, with an array of parameters.
1361      * <p>
1362      * This is a convenience method that can be used to log entry
1363      * to a method.  A LogRecord with message "ENTRY" (followed by a
1364      * format {N} indicator for each entry in the parameter array),
1365      * log level FINER, and the given sourceMethod, sourceClass, and
1366      * parameters is logged.
1367      *
1368      * @param   sourceClass    name of class that issued the logging request
1369      * @param   sourceMethod   name of method that is being entered
1370      * @param   params         array of parameters to the method being entered
1371      */
1372     public void entering(String sourceClass, String sourceMethod, Object params[]) {
1373         String msg = "ENTRY";
1374         if (params == null ) {
1375            logp(Level.FINER, sourceClass, sourceMethod, msg);
1376            return;
1377         }
1378         if (!isLoggable(Level.FINER)) return;
1379         for (int i = 0; i < params.length; i++) {
1380             msg = msg + " {" + i + "}";
1381         }
1382         logp(Level.FINER, sourceClass, sourceMethod, msg, params);
1383     }
1384 
1385     /**
1386      * Log a method return.
1387      * <p>
1388      * This is a convenience method that can be used to log returning
1389      * from a method.  A LogRecord with message "RETURN", log level
1390      * FINER, and the given sourceMethod and sourceClass is logged.
1391      *
1392      * @param   sourceClass    name of class that issued the logging request
1393      * @param   sourceMethod   name of the method
1394      */
1395     public void exiting(String sourceClass, String sourceMethod) {
1396         logp(Level.FINER, sourceClass, sourceMethod, "RETURN");
1397     }
1398 
1399 
1400     /**
1401      * Log a method return, with result object.
1402      * <p>
1403      * This is a convenience method that can be used to log returning
1404      * from a method.  A LogRecord with message "RETURN {0}", log level
1405      * FINER, and the gives sourceMethod, sourceClass, and result
1406      * object is logged.
1407      *
1408      * @param   sourceClass    name of class that issued the logging request
1409      * @param   sourceMethod   name of the method
1410      * @param   result  Object that is being returned
1411      */
1412     public void exiting(String sourceClass, String sourceMethod, Object result) {
1413         logp(Level.FINER, sourceClass, sourceMethod, "RETURN {0}", result);
1414     }
1415 
1416     /**
1417      * Log throwing an exception.
1418      * <p>
1419      * This is a convenience method to log that a method is
1420      * terminating by throwing an exception.  The logging is done
1421      * using the FINER level.
1422      * <p>
1423      * If the logger is currently enabled for the given message
1424      * level then the given arguments are stored in a LogRecord
1425      * which is forwarded to all registered output handlers.  The
1426      * LogRecord's message is set to "THROW".
1427      * <p>
1428      * Note that the thrown argument is stored in the LogRecord thrown
1429      * property, rather than the LogRecord parameters property.  Thus it is
1430      * processed specially by output Formatters and is not treated
1431      * as a formatting parameter to the LogRecord message property.
1432      *
1433      * @param   sourceClass    name of class that issued the logging request
1434      * @param   sourceMethod  name of the method.
1435      * @param   thrown  The Throwable that is being thrown.
1436      */
1437     public void throwing(String sourceClass, String sourceMethod, Throwable thrown) {
1438         if (!isLoggable(Level.FINER)) {
1439             return;
1440         }
1441         LogRecord lr = new LogRecord(Level.FINER, "THROW");
1442         lr.setSourceClassName(sourceClass);
1443         lr.setSourceMethodName(sourceMethod);
1444         lr.setThrown(thrown);
1445         doLog(lr);
1446     }
1447 
1448     //=======================================================================
1449     // Start of simple convenience methods using level names as method names
1450     //=======================================================================
1451 
1452     /**
1453      * Log a SEVERE message.
1454      * <p>
1455      * If the logger is currently enabled for the SEVERE message
1456      * level then the given message is forwarded to all the
1457      * registered output Handler objects.
1458      *
1459      * @param   msg     The string message (or a key in the message catalog)
1460      */
1461     public void severe(String msg) {
1462         log(Level.SEVERE, msg);
1463     }
1464 
1465     /**
1466      * Log a WARNING message.
1467      * <p>
1468      * If the logger is currently enabled for the WARNING message
1469      * level then the given message is forwarded to all the
1470      * registered output Handler objects.
1471      *
1472      * @param   msg     The string message (or a key in the message catalog)
1473      */
1474     public void warning(String msg) {
1475         log(Level.WARNING, msg);
1476     }
1477 
1478     /**
1479      * Log an INFO message.
1480      * <p>
1481      * If the logger is currently enabled for the INFO message
1482      * level then the given message is forwarded to all the
1483      * registered output Handler objects.
1484      *
1485      * @param   msg     The string message (or a key in the message catalog)
1486      */
1487     public void info(String msg) {
1488         log(Level.INFO, msg);
1489     }
1490 
1491     /**
1492      * Log a CONFIG message.
1493      * <p>
1494      * If the logger is currently enabled for the CONFIG message
1495      * level then the given message is forwarded to all the
1496      * registered output Handler objects.
1497      *
1498      * @param   msg     The string message (or a key in the message catalog)
1499      */
1500     public void config(String msg) {
1501         log(Level.CONFIG, msg);
1502     }
1503 
1504     /**
1505      * Log a FINE message.
1506      * <p>
1507      * If the logger is currently enabled for the FINE message
1508      * level then the given message is forwarded to all the
1509      * registered output Handler objects.
1510      *
1511      * @param   msg     The string message (or a key in the message catalog)
1512      */
1513     public void fine(String msg) {
1514         log(Level.FINE, msg);
1515     }
1516 
1517     /**
1518      * Log a FINER message.
1519      * <p>
1520      * If the logger is currently enabled for the FINER message
1521      * level then the given message is forwarded to all the
1522      * registered output Handler objects.
1523      *
1524      * @param   msg     The string message (or a key in the message catalog)
1525      */
1526     public void finer(String msg) {
1527         log(Level.FINER, msg);
1528     }
1529 
1530     /**
1531      * Log a FINEST message.
1532      * <p>
1533      * If the logger is currently enabled for the FINEST message
1534      * level then the given message is forwarded to all the
1535      * registered output Handler objects.
1536      *
1537      * @param   msg     The string message (or a key in the message catalog)
1538      */
1539     public void finest(String msg) {
1540         log(Level.FINEST, msg);
1541     }
1542 
1543     //=======================================================================
1544     // Start of simple convenience methods using level names as method names
1545     // and use Supplier<String>
1546     //=======================================================================
1547 
1548     /**
1549      * Log a SEVERE message, which is only to be constructed if the logging
1550      * level is such that the message will actually be logged.
1551      * <p>
1552      * If the logger is currently enabled for the SEVERE message
1553      * level then the message is constructed by invoking the provided
1554      * supplier function and forwarded to all the registered output
1555      * Handler objects.
1556      *
1557      * @param   msgSupplier   A function, which when called, produces the
1558      *                        desired log message
1559      * @since   1.8
1560      */
1561     public void severe(Supplier<String> msgSupplier) {
1562         log(Level.SEVERE, msgSupplier);
1563     }
1564 
1565     /**
1566      * Log a WARNING message, which is only to be constructed if the logging
1567      * level is such that the message will actually be logged.
1568      * <p>
1569      * If the logger is currently enabled for the WARNING message
1570      * level then the message is constructed by invoking the provided
1571      * supplier function and forwarded to all the registered output
1572      * Handler objects.
1573      *
1574      * @param   msgSupplier   A function, which when called, produces the
1575      *                        desired log message
1576      * @since   1.8
1577      */
1578     public void warning(Supplier<String> msgSupplier) {
1579         log(Level.WARNING, msgSupplier);
1580     }
1581 
1582     /**
1583      * Log a INFO message, which is only to be constructed if the logging
1584      * level is such that the message will actually be logged.
1585      * <p>
1586      * If the logger is currently enabled for the INFO message
1587      * level then the message is constructed by invoking the provided
1588      * supplier function and forwarded to all the registered output
1589      * Handler objects.
1590      *
1591      * @param   msgSupplier   A function, which when called, produces the
1592      *                        desired log message
1593      * @since   1.8
1594      */
1595     public void info(Supplier<String> msgSupplier) {
1596         log(Level.INFO, msgSupplier);
1597     }
1598 
1599     /**
1600      * Log a CONFIG message, which is only to be constructed if the logging
1601      * level is such that the message will actually be logged.
1602      * <p>
1603      * If the logger is currently enabled for the CONFIG message
1604      * level then the message is constructed by invoking the provided
1605      * supplier function and forwarded to all the registered output
1606      * Handler objects.
1607      *
1608      * @param   msgSupplier   A function, which when called, produces the
1609      *                        desired log message
1610      * @since   1.8
1611      */
1612     public void config(Supplier<String> msgSupplier) {
1613         log(Level.CONFIG, msgSupplier);
1614     }
1615 
1616     /**
1617      * Log a FINE message, which is only to be constructed if the logging
1618      * level is such that the message will actually be logged.
1619      * <p>
1620      * If the logger is currently enabled for the FINE message
1621      * level then the message is constructed by invoking the provided
1622      * supplier function and forwarded to all the registered output
1623      * Handler objects.
1624      *
1625      * @param   msgSupplier   A function, which when called, produces the
1626      *                        desired log message
1627      * @since   1.8
1628      */
1629     public void fine(Supplier<String> msgSupplier) {
1630         log(Level.FINE, msgSupplier);
1631     }
1632 
1633     /**
1634      * Log a FINER message, which is only to be constructed if the logging
1635      * level is such that the message will actually be logged.
1636      * <p>
1637      * If the logger is currently enabled for the FINER message
1638      * level then the message is constructed by invoking the provided
1639      * supplier function and forwarded to all the registered output
1640      * Handler objects.
1641      *
1642      * @param   msgSupplier   A function, which when called, produces the
1643      *                        desired log message
1644      * @since   1.8
1645      */
1646     public void finer(Supplier<String> msgSupplier) {
1647         log(Level.FINER, msgSupplier);
1648     }
1649 
1650     /**
1651      * Log a FINEST message, which is only to be constructed if the logging
1652      * level is such that the message will actually be logged.
1653      * <p>
1654      * If the logger is currently enabled for the FINEST message
1655      * level then the message is constructed by invoking the provided
1656      * supplier function and forwarded to all the registered output
1657      * Handler objects.
1658      *
1659      * @param   msgSupplier   A function, which when called, produces the
1660      *                        desired log message
1661      * @since   1.8
1662      */
1663     public void finest(Supplier<String> msgSupplier) {
1664         log(Level.FINEST, msgSupplier);
1665     }
1666 
1667     //================================================================
1668     // End of convenience methods
1669     //================================================================
1670 
1671     /**
1672      * Set the log level specifying which message levels will be
1673      * logged by this logger.  Message levels lower than this
1674      * value will be discarded.  The level value Level.OFF
1675      * can be used to turn off logging.
1676      * <p>
1677      * If the new level is null, it means that this node should
1678      * inherit its level from its nearest ancestor with a specific


1751     /**
1752      * Remove a log Handler.
1753      * <P>
1754      * Returns silently if the given Handler is not found or is null
1755      *
1756      * @param   handler a logging Handler
1757      * @throws  SecurityException if a security manager exists,
1758      *          this logger is not anonymous, and the caller
1759      *          does not have LoggingPermission("control").
1760      */
1761     public void removeHandler(Handler handler) throws SecurityException {
1762         checkPermission();
1763         if (handler == null) {
1764             return;
1765         }
1766         handlers.remove(handler);
1767     }
1768 
1769     /**
1770      * Get the Handlers associated with this logger.
1771      *
1772      * @return  an array of all registered Handlers
1773      */
1774     public Handler[] getHandlers() {
1775         return accessCheckedHandlers();
1776     }
1777 
1778     // This method should ideally be marked final - but unfortunately
1779     // it needs to be overridden by LogManager.RootLogger
1780     Handler[] accessCheckedHandlers() {
1781         return handlers.toArray(emptyHandlers);
1782     }
1783 
1784     /**
1785      * Specify whether or not this logger should send its output
1786      * to its parent Logger.  This means that any LogRecords will
1787      * also be written to the parent's Handlers, and potentially
1788      * to its parent, recursively up the namespace.
1789      *
1790      * @param useParentHandlers   true if output is to be sent to the
1791      *          logger's parent.


1997      * <p>
1998      * The result will be null if it is called on the root Logger
1999      * in the namespace.
2000      *
2001      * @return nearest existing parent Logger
2002      */
2003     public Logger getParent() {
2004         // Note: this used to be synchronized on treeLock.  However, this only
2005         // provided memory semantics, as there was no guarantee that the caller
2006         // would synchronize on treeLock (in fact, there is no way for external
2007         // callers to so synchronize).  Therefore, we have made parent volatile
2008         // instead.
2009         return parent;
2010     }
2011 
2012     /**
2013      * Set the parent for this Logger.  This method is used by
2014      * the LogManager to update a Logger when the namespace changes.
2015      * <p>
2016      * It should not be called from application code.
2017      *
2018      * @param  parent   the new parent logger
2019      * @throws  SecurityException  if a security manager exists and if
2020      *          the caller does not have LoggingPermission("control").
2021      */
2022     public void setParent(Logger parent) {
2023         if (parent == null) {
2024             throw new NullPointerException();
2025         }
2026 
2027         // check permission for all loggers, including anonymous loggers
2028         if (manager == null) {
2029             manager = LogManager.getLogManager();
2030         }
2031         manager.checkPermission();
2032 
2033         doSetParent(parent);
2034     }
2035 
2036     // Private method to do the work for parenting a child
2037     // Logger onto a parent logger.