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

Print this page




 227 
 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 


 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) {




 227 
 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         if (global != null && global.manager == null) {
 248             // Complete initialization of the global Logger.
 249             // In practice this should never happen - unless getGlobal() is called
 250             // from within a subclass of LogManager being installed as
 251             // global LogManager - in which case LogManager.getLogManager() will
 252             // return null anyway...
 253             global.manager = LogManager.getLogManager();
 254         }
 255 
 256         // To prevent race conditions we also need to ensure that
 257         // the global logger was added the log manager.
 258         // We do that here. It will either initialize the manager
 259         // or wait for it to be initialized.
 260         // Indeed global.manager will become not null somewhen during
 261         // the initalization of LogManager.
 262         // If two threads are calling getGlobal() concurrently, one thread
 263         // will see global.manager null and call LogMnager.getLogManager(),
 264         // but the other thread could come in at a time when global.manager
 265         // is already set although ensureLogManagerInitialized is not finished
 266         // yet...
 267         // Calling manager.ensureLogManagerInitialized() should fix that.
 268         if (global.manager !=  null) {
 269             global.manager.ensureLogManagerInitialized();
 270         }
 271 
 272         // Now the global LogManager should be initialized,
 273         // and the global logger should have been added to
 274         // it, unless we where called within the constructor of a LogManager
 275         // subclass installed as LogManager, in which case global.manager
 276         // would still be null, and global will be lazily initialized later on.
 277 
 278         return global;
 279     }
 280 
 281     /**
 282      * The "global" Logger object is provided as a convenience to developers
 283      * who are making casual use of the Logging package.  Developers
 284      * who are making serious use of the logging package (for example
 285      * in products) should create and use their own Logger objects,
 286      * with appropriate names, so that logging can be controlled on a
 287      * suitable per-Logger granularity. Developers also need to keep a
 288      * strong reference to their Logger objects to prevent them from
 289      * being garbage collected.
 290      * <p>
 291      * @deprecated Initialization of this field is prone to deadlocks.
 292      * The field must be initialized by the Logger class initialization
 293      * which may cause deadlocks with the LogManager class initialization.
 294      * In such cases two class initialization wait for each other to complete.
 295      * The preferred way to get the global logger object is via the call
 296      * <code>Logger.getGlobal()</code>.
 297      * For compatibility with old JDK versions where the


 303     public static final Logger global = new Logger(GLOBAL_LOGGER_NAME);
 304 
 305     /**
 306      * Protected method to construct a logger for a named subsystem.
 307      * <p>
 308      * The logger will be initially configured with a null Level
 309      * and with useParentHandlers set to true.
 310      *
 311      * @param   name    A name for the logger.  This should
 312      *                          be a dot-separated name and should normally
 313      *                          be based on the package name or class name
 314      *                          of the subsystem, such as java.net
 315      *                          or javax.swing.  It may be null for anonymous Loggers.
 316      * @param   resourceBundleName  name of ResourceBundle to be used for localizing
 317      *                          messages for this logger.  May be null if none
 318      *                          of the messages require localization.
 319      * @throws MissingResourceException if the resourceBundleName is non-null and
 320      *             no corresponding resource can be found.
 321      */
 322     protected Logger(String name, String resourceBundleName) {
 323         this(name, resourceBundleName, null, LogManager.getLogManager());
 324     }
 325 
 326     Logger(String name, String resourceBundleName, Class<?> caller, LogManager manager) {
 327         this.manager = manager;
 328         setupResourceInfo(resourceBundleName, caller);
 329         this.name = name;
 330         levelValue = Level.INFO.intValue();
 331     }
 332 
 333     private void setCallersClassLoaderRef(Class<?> caller) {
 334         ClassLoader callersClassLoader = ((caller != null)
 335                                          ? caller.getClassLoader()
 336                                          : null);
 337         if (callersClassLoader != null) {
 338             this.callersClassLoaderRef = new WeakReference(callersClassLoader);
 339         }
 340     }
 341 
 342     private ClassLoader getCallersClassLoader() {
 343         return (callersClassLoaderRef != null)
 344                 ? callersClassLoaderRef.get()
 345                 : null;
 346     }
 347 


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


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