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

Print this page
rev 7022 : 8013380: Removal of stack walk to find resource bundle breaks Glassfish startup
Summary: Use caller's classloader to load resource as an alternative to thread context classloader and system classloader
Reviewed-by: duke

*** 216,225 **** --- 216,226 ---- // references from children to parents. private volatile Logger parent; // our nearest parent. private ArrayList<LogManager.LoggerWeakRef> kids; // WeakReferences to loggers that have us as parent private volatile Level levelObject; private volatile int levelValue; // current effective level value + private WeakReference<ClassLoader> callersClassLoaderRef; /** * GLOBAL_LOGGER_NAME is a name for the global logger. * * @since 1.6
*** 275,292 **** * messages for this logger. May be null if none * of the messages require localization. * @throws MissingResourceException if the resourceBundleName is non-null and * no corresponding resource can be found. */ protected Logger(String name, String resourceBundleName) { this.manager = LogManager.getLogManager(); if (resourceBundleName != null) { // MissingResourceException or IllegalArgumentException can // be thrown by setupResourceInfo(). Since this is the Logger // constructor, the resourceBundleName field is null so // IllegalArgumentException cannot happen here. ! setupResourceInfo(resourceBundleName); } this.name = name; levelValue = Level.INFO.intValue(); } --- 276,301 ---- * messages for this logger. May be null if none * of the messages require localization. * @throws MissingResourceException if the resourceBundleName is non-null and * no corresponding resource can be found. */ + @CallerSensitive protected Logger(String name, String resourceBundleName) { + this(name, resourceBundleName, + Reflection.getCallerClass().getClassLoader()); + } + + Logger(String name, String resourceBundleName, + ClassLoader callersClassLoader) { this.manager = LogManager.getLogManager(); + this.callersClassLoaderRef = new WeakReference(callersClassLoader); if (resourceBundleName != null) { // MissingResourceException or IllegalArgumentException can // be thrown by setupResourceInfo(). Since this is the Logger // constructor, the resourceBundleName field is null so // IllegalArgumentException cannot happen here. ! setupResourceInfo(resourceBundleName, callersClassLoader); } this.name = name; levelValue = Level.INFO.intValue(); }
*** 341,351 **** if (sm != null && !SystemLoggerHelper.disableCallerCheck) { if (caller.getClassLoader() == null) { return manager.demandSystemLogger(name, resourceBundleName); } } ! return manager.demandLogger(name, resourceBundleName); } /** * Find or create a logger for a named subsystem. If a logger has * already been created with the given name it is returned. Otherwise --- 350,361 ---- if (sm != null && !SystemLoggerHelper.disableCallerCheck) { if (caller.getClassLoader() == null) { return manager.demandSystemLogger(name, resourceBundleName); } } ! return manager.demandLogger(name, resourceBundleName, ! caller.getClassLoader()); } /** * Find or create a logger for a named subsystem. If a logger has * already been created with the given name it is returned. Otherwise
*** 434,448 **** // Synchronization is not required here. All synchronization for // adding a new Logger object is handled by LogManager.addLogger(). @CallerSensitive public static Logger getLogger(String name, String resourceBundleName) { ! Logger result = demandLogger(name, resourceBundleName, Reflection.getCallerClass()); // MissingResourceException or IllegalArgumentException can be // thrown by setupResourceInfo(). ! result.setupResourceInfo(resourceBundleName); return result; } // package-private // Add a platform logger to the system context. --- 444,459 ---- // Synchronization is not required here. All synchronization for // adding a new Logger object is handled by LogManager.addLogger(). @CallerSensitive public static Logger getLogger(String name, String resourceBundleName) { ! Class callerClass = Reflection.getCallerClass(); ! Logger result = demandLogger(name, resourceBundleName, callerClass); // MissingResourceException or IllegalArgumentException can be // thrown by setupResourceInfo(). ! result.setupResourceInfo(resourceBundleName, callerClass.getClassLoader()); return result; } // package-private // Add a platform logger to the system context.
*** 525,535 **** * bundle inherited from its parent. * * @return localization bundle (may be null) */ public ResourceBundle getResourceBundle() { ! return findResourceBundle(getResourceBundleName()); } /** * Retrieve the localization resource bundle name for this * logger. Note that if the result is null, then the Logger --- 536,548 ---- * bundle inherited from its parent. * * @return localization bundle (may be null) */ public ResourceBundle getResourceBundle() { ! return findResourceBundle(getResourceBundleName(), ! (callersClassLoaderRef != null ? callersClassLoaderRef.get() : ! null)); } /** * Retrieve the localization resource bundle name for this * logger. Note that if the result is null, then the Logger
*** 607,617 **** private void doLog(LogRecord lr) { lr.setLoggerName(name); String ebname = getEffectiveResourceBundleName(); if (ebname != null && !ebname.equals(SYSTEM_LOGGER_RB_NAME)) { lr.setResourceBundleName(ebname); ! lr.setResourceBundle(findResourceBundle(ebname)); } log(lr); } --- 620,633 ---- private void doLog(LogRecord lr) { lr.setLoggerName(name); String ebname = getEffectiveResourceBundleName(); if (ebname != null && !ebname.equals(SYSTEM_LOGGER_RB_NAME)) { lr.setResourceBundleName(ebname); ! lr.setResourceBundle(findResourceBundle(ebname, ! (callersClassLoaderRef != null ! ? callersClassLoaderRef.get() ! : null))); } log(lr); }
*** 934,944 **** // resource bundle and then call "void log(LogRecord)". private void doLog(LogRecord lr, String rbname) { lr.setLoggerName(name); if (rbname != null) { lr.setResourceBundleName(rbname); ! lr.setResourceBundle(findResourceBundle(rbname)); } log(lr); } /** --- 950,963 ---- // resource bundle and then call "void log(LogRecord)". private void doLog(LogRecord lr, String rbname) { lr.setLoggerName(name); if (rbname != null) { lr.setResourceBundleName(rbname); ! lr.setResourceBundle(findResourceBundle(rbname, ! (callersClassLoaderRef != null ! ? callersClassLoaderRef.get() ! : null))); } log(lr); } /**
*** 1609,1619 **** * there is no suitable previous cached value. * * @param name the ResourceBundle to locate * @return ResourceBundle specified by name or null if not found */ ! private synchronized ResourceBundle findResourceBundle(String name) { // Return a null bundle for a null name. if (name == null) { return null; } --- 1628,1639 ---- * there is no suitable previous cached value. * * @param name the ResourceBundle to locate * @return ResourceBundle specified by name or null if not found */ ! private synchronized ResourceBundle findResourceBundle(String name, ! ClassLoader callersClassLoader) { // Return a null bundle for a null name. if (name == null) { return null; }
*** 1642,1662 **** catalog = ResourceBundle.getBundle(name, currentLocale, cl); catalogName = name; catalogLocale = currentLocale; return catalog; } catch (MissingResourceException ex) { return null; } } // Private utility method to initialize our one entry // resource bundle name cache. // Note: for consistency reasons, we are careful to check // that a suitable ResourceBundle exists before setting the // resourceBundleName field. // Synchronized to prevent races in setting the field. ! private synchronized void setupResourceInfo(String name) { if (name == null) { return; } if (resourceBundleName != null) { --- 1662,1699 ---- catalog = ResourceBundle.getBundle(name, currentLocale, cl); catalogName = name; catalogLocale = currentLocale; return catalog; } catch (MissingResourceException ex) { + // Woops. We can't find the ResourceBundle in the default + // ClassLoader. Drop through. + } + + // Try with the caller's ClassLoader + if (callersClassLoader == null) { return null; } + + try { + catalog = ResourceBundle.getBundle(name, currentLocale, + callersClassLoader); + catalogName = name; + catalogLocale = currentLocale; + return catalog; + } catch (MissingResourceException ex) { + return null; // no luck + } } // Private utility method to initialize our one entry // resource bundle name cache. // Note: for consistency reasons, we are careful to check // that a suitable ResourceBundle exists before setting the // resourceBundleName field. // Synchronized to prevent races in setting the field. ! private synchronized void setupResourceInfo(String name, ! ClassLoader callersClassLoader) { if (name == null) { return; } if (resourceBundleName != null) {
*** 1670,1682 **** // cannot change ResourceBundles once they are set throw new IllegalArgumentException( resourceBundleName + " != " + name); } ! if (findResourceBundle(name) == null) { // We've failed to find an expected ResourceBundle. ! throw new MissingResourceException("Can't find " + name + " bundle", name, ""); } resourceBundleName = name; } /** --- 1707,1720 ---- // cannot change ResourceBundles once they are set throw new IllegalArgumentException( resourceBundleName + " != " + name); } ! if (findResourceBundle(name, callersClassLoader) == null) { // We've failed to find an expected ResourceBundle. ! throw new MissingResourceException("Can't find " + name + " bundle", ! name, ""); } resourceBundleName = name; } /**