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

Print this page




 228     /**
 229      * Return global logger object with the name Logger.GLOBAL_LOGGER_NAME.
 230      *
 231      * @return global logger object
 232      * @since 1.7
 233      */
 234     public static final Logger getGlobal() {
 235         // In order to break a cyclic dependence between the LogManager
 236         // and Logger static initializers causing deadlocks, the global
 237         // logger is created with a special constructor that does not
 238         // initialize its log manager.
 239         //
 240         // If an application calls Logger.getGlobal() before any logger
 241         // has been initialized, it is therefore possible that the
 242         // LogManager class has not been initialized yet, and therefore
 243         // Logger.global.manager will be null.
 244         //
 245         // In order to finish the initialization of the global logger, we
 246         // will therefore call LogManager.getLogManager() here.
 247         //
 248         // Care must be taken *not* to call Logger.getGlobal() in
 249         // LogManager static initializers in order to avoid such
 250         // deadlocks.
 251         //
 252         if (global != null && global.manager == null) {
 253             // Complete initialization of the global Logger.
 254             global.manager = LogManager.getLogManager();
 255         }












 256         return global;
 257     }
 258 
 259     /**
 260      * The "global" Logger object is provided as a convenience to developers
 261      * who are making casual use of the Logging package.  Developers
 262      * who are making serious use of the logging package (for example
 263      * in products) should create and use their own Logger objects,
 264      * with appropriate names, so that logging can be controlled on a
 265      * suitable per-Logger granularity. Developers also need to keep a
 266      * strong reference to their Logger objects to prevent them from
 267      * being garbage collected.
 268      * <p>
 269      * @deprecated Initialization of this field is prone to deadlocks.
 270      * The field must be initialized by the Logger class initialization
 271      * which may cause deadlocks with the LogManager class initialization.
 272      * In such cases two class initialization wait for each other to complete.
 273      * The preferred way to get the global logger object is via the call
 274      * <code>Logger.getGlobal()</code>.
 275      * For compatibility with old JDK versions where the


 281     public static final Logger global = new Logger(GLOBAL_LOGGER_NAME);
 282 
 283     /**
 284      * Protected method to construct a logger for a named subsystem.
 285      * <p>
 286      * The logger will be initially configured with a null Level
 287      * and with useParentHandlers set to true.
 288      *
 289      * @param   name    A name for the logger.  This should
 290      *                          be a dot-separated name and should normally
 291      *                          be based on the package name or class name
 292      *                          of the subsystem, such as java.net
 293      *                          or javax.swing.  It may be null for anonymous Loggers.
 294      * @param   resourceBundleName  name of ResourceBundle to be used for localizing
 295      *                          messages for this logger.  May be null if none
 296      *                          of the messages require localization.
 297      * @throws MissingResourceException if the resourceBundleName is non-null and
 298      *             no corresponding resource can be found.
 299      */
 300     protected Logger(String name, String resourceBundleName) {
 301         this(name, resourceBundleName, null);
 302     }
 303 
 304     Logger(String name, String resourceBundleName, Class<?> caller) {
 305         this.manager = LogManager.getLogManager();
 306         setupResourceInfo(resourceBundleName, caller);
 307         this.name = name;
 308         levelValue = Level.INFO.intValue();
 309     }
 310 
 311     private void setCallersClassLoaderRef(Class<?> caller) {
 312         ClassLoader callersClassLoader = ((caller != null)
 313                                          ? caller.getClassLoader()
 314                                          : null);
 315         if (callersClassLoader != null) {
 316             this.callersClassLoaderRef = new WeakReference(callersClassLoader);
 317         }
 318     }
 319 
 320     private ClassLoader getCallersClassLoader() {
 321         return (callersClassLoaderRef != null)
 322                 ? callersClassLoaderRef.get()
 323                 : null;
 324     }
 325 
 326     // This constructor is used only to create the global Logger.
 327     // It is needed to break a cyclic dependence between the LogManager
 328     // and Logger static initializers causing deadlocks.
 329     private Logger(String name) {
 330         // The manager field is not initialized here.
 331         this.name = name;
 332         levelValue = Level.INFO.intValue();
 333     }
 334 
 335     // It is called from the LogManager.<clinit> to complete
 336     // initialization of the global Logger.
 337     void setLogManager(LogManager manager) {
 338         this.manager = manager;
 339     }
 340 
 341     private void checkPermission() throws SecurityException {
 342         if (!anonymous) {
 343             if (manager == null) {
 344                 // Complete initialization of the global Logger.
 345                 manager = LogManager.getLogManager();
 346             }
 347             manager.checkPermission();
 348         }
 349     }
 350 
 351     // Until all JDK code converted to call sun.util.logging.PlatformLogger
 352     // (see 7054233), we need to determine if Logger.getLogger is to add
 353     // a system logger or user logger.
 354     //
 355     // As an interim solution, if the immediate caller whose caller loader is
 356     // null, we assume it's a system logger and add it to the system context.


 541      * to have the root logger ("") as its parent.  This means that
 542      * by default it inherits its effective level and handlers
 543      * from the root logger.
 544      * <p>
 545      * @param   resourceBundleName  name of ResourceBundle to be used for localizing
 546      *                          messages for this logger.
 547      *          May be null if none of the messages require localization.
 548      * @return a newly created private Logger
 549      * @throws MissingResourceException if the resourceBundleName is non-null and
 550      *             no corresponding resource can be found.
 551      */
 552 
 553     // Synchronization is not required here. All synchronization for
 554     // adding a new anonymous Logger object is handled by doSetParent().
 555     @CallerSensitive
 556     public static Logger getAnonymousLogger(String resourceBundleName) {
 557         LogManager manager = LogManager.getLogManager();
 558         // cleanup some Loggers that have been GC'ed
 559         manager.drainLoggerRefQueueBounded();
 560         Logger result = new Logger(null, resourceBundleName,
 561                                    Reflection.getCallerClass());
 562         result.anonymous = true;
 563         Logger root = manager.getLogger("");
 564         result.doSetParent(root);
 565         return result;
 566     }
 567 
 568     /**
 569      * Retrieve the localization resource bundle for this
 570      * logger for the current default locale.  Note that if
 571      * the result is null, then the Logger will use a resource
 572      * bundle inherited from its parent.
 573      *
 574      * @return localization bundle (may be null)
 575      */
 576     public ResourceBundle getResourceBundle() {
 577         return findResourceBundle(getResourceBundleName(), true);
 578     }
 579 
 580     /**
 581      * Retrieve the localization resource bundle name for this


1781         // would synchronize on treeLock (in fact, there is no way for external
1782         // callers to so synchronize).  Therefore, we have made parent volatile
1783         // instead.
1784         return parent;
1785     }
1786 
1787     /**
1788      * Set the parent for this Logger.  This method is used by
1789      * the LogManager to update a Logger when the namespace changes.
1790      * <p>
1791      * It should not be called from application code.
1792      * <p>
1793      * @param  parent   the new parent logger
1794      * @exception  SecurityException  if a security manager exists and if
1795      *             the caller does not have LoggingPermission("control").
1796      */
1797     public void setParent(Logger parent) {
1798         if (parent == null) {
1799             throw new NullPointerException();
1800         }
1801         manager.checkPermission();
1802         doSetParent(parent);
1803     }
1804 
1805     // Private method to do the work for parenting a child
1806     // Logger onto a parent logger.
1807     private void doSetParent(Logger newParent) {
1808 
1809         // System.err.println("doSetParent \"" + getName() + "\" \""
1810         //                              + newParent.getName() + "\"");
1811 
1812         synchronized (treeLock) {
1813 
1814             // Remove ourself from any previous parent.
1815             LogManager.LoggerWeakRef ref = null;
1816             if (parent != null) {
1817                 // assert parent.kids != null;
1818                 for (Iterator<LogManager.LoggerWeakRef> iter = parent.kids.iterator(); iter.hasNext(); ) {
1819                     ref = iter.next();
1820                     Logger kid =  ref.get();
1821                     if (kid == this) {




 228     /**
 229      * Return global logger object with the name Logger.GLOBAL_LOGGER_NAME.
 230      *
 231      * @return global logger object
 232      * @since 1.7
 233      */
 234     public static final Logger getGlobal() {
 235         // In order to break a cyclic dependence between the LogManager
 236         // and Logger static initializers causing deadlocks, the global
 237         // logger is created with a special constructor that does not
 238         // initialize its log manager.
 239         //
 240         // If an application calls Logger.getGlobal() before any logger
 241         // has been initialized, it is therefore possible that the
 242         // LogManager class has not been initialized yet, and therefore
 243         // Logger.global.manager will be null.
 244         //
 245         // In order to finish the initialization of the global logger, we
 246         // will therefore call LogManager.getLogManager() here.
 247         //
 248         // To prevent race conditions we also need to call
 249         // LogManager.getLogManager() unconditionally here.
 250         // Indeed we cannot rely on the observed value of global.manager,
 251         // because global.manager will become not null somewhere during
 252         // the initialization of LogManager.
 253         // If two threads are calling getGlobal() concurrently, one thread
 254         // will see global.manager null and call LogManager.getLogManager(),
 255         // but the other thread could come in at a time when global.manager
 256         // is already set although ensureLogManagerInitialized is not finished
 257         // yet...
 258         // Calling LogManager.getLogManager() unconditionally will fix that.
 259 
 260         LogManager.getLogManager();
 261 
 262         // Now the global LogManager should be initialized,
 263         // and the global logger should have been added to
 264         // it, unless we were called within the constructor of a LogManager
 265         // subclass installed as LogManager, in which case global.manager
 266         // would still be null, and global will be lazily initialized later on.
 267 
 268         return global;
 269     }
 270 
 271     /**
 272      * The "global" Logger object is provided as a convenience to developers
 273      * who are making casual use of the Logging package.  Developers
 274      * who are making serious use of the logging package (for example
 275      * in products) should create and use their own Logger objects,
 276      * with appropriate names, so that logging can be controlled on a
 277      * suitable per-Logger granularity. Developers also need to keep a
 278      * strong reference to their Logger objects to prevent them from
 279      * being garbage collected.
 280      * <p>
 281      * @deprecated Initialization of this field is prone to deadlocks.
 282      * The field must be initialized by the Logger class initialization
 283      * which may cause deadlocks with the LogManager class initialization.
 284      * In such cases two class initialization wait for each other to complete.
 285      * The preferred way to get the global logger object is via the call
 286      * <code>Logger.getGlobal()</code>.
 287      * For compatibility with old JDK versions where the


 293     public static final Logger global = new Logger(GLOBAL_LOGGER_NAME);
 294 
 295     /**
 296      * Protected method to construct a logger for a named subsystem.
 297      * <p>
 298      * The logger will be initially configured with a null Level
 299      * and with useParentHandlers set to true.
 300      *
 301      * @param   name    A name for the logger.  This should
 302      *                          be a dot-separated name and should normally
 303      *                          be based on the package name or class name
 304      *                          of the subsystem, such as java.net
 305      *                          or javax.swing.  It may be null for anonymous Loggers.
 306      * @param   resourceBundleName  name of ResourceBundle to be used for localizing
 307      *                          messages for this logger.  May be null if none
 308      *                          of the messages require localization.
 309      * @throws MissingResourceException if the resourceBundleName is non-null and
 310      *             no corresponding resource can be found.
 311      */
 312     protected Logger(String name, String resourceBundleName) {
 313         this(name, resourceBundleName, null, LogManager.getLogManager());
 314     }
 315 
 316     Logger(String name, String resourceBundleName, Class<?> caller, LogManager manager) {
 317         this.manager = manager;
 318         setupResourceInfo(resourceBundleName, caller);
 319         this.name = name;
 320         levelValue = Level.INFO.intValue();
 321     }
 322 
 323     private void setCallersClassLoaderRef(Class<?> caller) {
 324         ClassLoader callersClassLoader = ((caller != null)
 325                                          ? caller.getClassLoader()
 326                                          : null);
 327         if (callersClassLoader != null) {
 328             this.callersClassLoaderRef = new WeakReference(callersClassLoader);
 329         }
 330     }
 331 
 332     private ClassLoader getCallersClassLoader() {
 333         return (callersClassLoaderRef != null)
 334                 ? callersClassLoaderRef.get()
 335                 : null;
 336     }
 337 
 338     // This constructor is used only to create the global Logger.
 339     // It is needed to break a cyclic dependence between the LogManager
 340     // and Logger static initializers causing deadlocks.
 341     private Logger(String name) {
 342         // The manager field is not initialized here.
 343         this.name = name;
 344         levelValue = Level.INFO.intValue();
 345     }
 346 
 347     // It is called from LoggerContext.addLocalLogger() when the logger
 348     // is actually added to a LogManager.
 349     void setLogManager(LogManager manager) {
 350         this.manager = manager;
 351     }
 352 
 353     private void checkPermission() throws SecurityException {
 354         if (!anonymous) {
 355             if (manager == null) {
 356                 // Complete initialization of the global Logger.
 357                 manager = LogManager.getLogManager();
 358             }
 359             manager.checkPermission();
 360         }
 361     }
 362 
 363     // Until all JDK code converted to call sun.util.logging.PlatformLogger
 364     // (see 7054233), we need to determine if Logger.getLogger is to add
 365     // a system logger or user logger.
 366     //
 367     // As an interim solution, if the immediate caller whose caller loader is
 368     // null, we assume it's a system logger and add it to the system context.


 553      * to have the root logger ("") as its parent.  This means that
 554      * by default it inherits its effective level and handlers
 555      * from the root logger.
 556      * <p>
 557      * @param   resourceBundleName  name of ResourceBundle to be used for localizing
 558      *                          messages for this logger.
 559      *          May be null if none of the messages require localization.
 560      * @return a newly created private Logger
 561      * @throws MissingResourceException if the resourceBundleName is non-null and
 562      *             no corresponding resource can be found.
 563      */
 564 
 565     // Synchronization is not required here. All synchronization for
 566     // adding a new anonymous Logger object is handled by doSetParent().
 567     @CallerSensitive
 568     public static Logger getAnonymousLogger(String resourceBundleName) {
 569         LogManager manager = LogManager.getLogManager();
 570         // cleanup some Loggers that have been GC'ed
 571         manager.drainLoggerRefQueueBounded();
 572         Logger result = new Logger(null, resourceBundleName,
 573                                    Reflection.getCallerClass(), manager);
 574         result.anonymous = true;
 575         Logger root = manager.getLogger("");
 576         result.doSetParent(root);
 577         return result;
 578     }
 579 
 580     /**
 581      * Retrieve the localization resource bundle for this
 582      * logger for the current default locale.  Note that if
 583      * the result is null, then the Logger will use a resource
 584      * bundle inherited from its parent.
 585      *
 586      * @return localization bundle (may be null)
 587      */
 588     public ResourceBundle getResourceBundle() {
 589         return findResourceBundle(getResourceBundleName(), true);
 590     }
 591 
 592     /**
 593      * Retrieve the localization resource bundle name for this


1793         // would synchronize on treeLock (in fact, there is no way for external
1794         // callers to so synchronize).  Therefore, we have made parent volatile
1795         // instead.
1796         return parent;
1797     }
1798 
1799     /**
1800      * Set the parent for this Logger.  This method is used by
1801      * the LogManager to update a Logger when the namespace changes.
1802      * <p>
1803      * It should not be called from application code.
1804      * <p>
1805      * @param  parent   the new parent logger
1806      * @exception  SecurityException  if a security manager exists and if
1807      *             the caller does not have LoggingPermission("control").
1808      */
1809     public void setParent(Logger parent) {
1810         if (parent == null) {
1811             throw new NullPointerException();
1812         }
1813         checkPermission();
1814         doSetParent(parent);
1815     }
1816 
1817     // Private method to do the work for parenting a child
1818     // Logger onto a parent logger.
1819     private void doSetParent(Logger newParent) {
1820 
1821         // System.err.println("doSetParent \"" + getName() + "\" \""
1822         //                              + newParent.getName() + "\"");
1823 
1824         synchronized (treeLock) {
1825 
1826             // Remove ourself from any previous parent.
1827             LogManager.LoggerWeakRef ref = null;
1828             if (parent != null) {
1829                 // assert parent.kids != null;
1830                 for (Iterator<LogManager.LoggerWeakRef> iter = parent.kids.iterator(); iter.hasNext(); ) {
1831                     ref = iter.next();
1832                     Logger kid =  ref.get();
1833                     if (kid == this) {