--- old/src/share/classes/java/util/logging/Logger.java 2013-11-27 18:16:56.000000000 +0100 +++ new/src/share/classes/java/util/logging/Logger.java 2013-11-27 18:16:55.000000000 +0100 @@ -218,12 +218,46 @@ public class Logger { private static final Handler emptyHandlers[] = new Handler[0]; private static final int offValue = Level.OFF.intValue(); - private LogManager manager; + + static final String SYSTEM_LOGGER_RB_NAME = "sun.util.logging.resources.logging"; + + // This class is immutable and it is important that it remains so. + private static final class LoggerBundle { + final String resourceBundleName; // Base name of the bundle. + final ResourceBundle userBundle; // Bundle set through setResourceBundle. + private LoggerBundle(String resourceBundleName, ResourceBundle bundle) { + this.resourceBundleName = resourceBundleName; + this.userBundle = bundle; + } + boolean isSystemBundle() { + return SYSTEM_LOGGER_RB_NAME.equals(resourceBundleName); + } + static LoggerBundle get(String name, ResourceBundle bundle) { + if (name == null && bundle == null) { + return NO_RESOURCE_BUNDLE; + } else if (SYSTEM_LOGGER_RB_NAME.equals(name) && bundle == null) { + return SYSTEM_BUNDLE; + } else { + return new LoggerBundle(name, bundle); + } + } + } + + // This instance will be shared by all loggers created by the system + // code + private static final LoggerBundle SYSTEM_BUNDLE = + new LoggerBundle(SYSTEM_LOGGER_RB_NAME, null); + + // This instance indicates that no resource bundle has been specified yet, + // and it will be shared by all loggers which have no resource bundle. + private static final LoggerBundle NO_RESOURCE_BUNDLE = + new LoggerBundle(null, null); + + private volatile LogManager manager; private String name; private final CopyOnWriteArrayList handlers = new CopyOnWriteArrayList<>(); - private String resourceBundleName; // Base name of the bundle. - private ResourceBundle userBundle; // Bundle set through setResourceBundle. + private volatile LoggerBundle loggerBundle = NO_RESOURCE_BUNDLE; private volatile boolean useParentHandlers = true; private volatile Filter filter; private boolean anonymous; @@ -341,6 +375,7 @@ Logger(String name, String resourceBundleName, Class caller, LogManager manager) { this.manager = manager; + assert this.loggerBundle == NO_RESOURCE_BUNDLE; setupResourceInfo(resourceBundleName, caller); this.name = name; levelValue = Level.INFO.intValue(); @@ -366,6 +401,7 @@ // and Logger static initializers causing deadlocks. private Logger(String name) { // The manager field is not initialized here. + assert this.loggerBundle == NO_RESOURCE_BUNDLE; this.name = name; levelValue = Level.INFO.intValue(); } @@ -641,7 +677,7 @@ * @return localization bundle name (may be {@code null}) */ public String getResourceBundleName() { - return resourceBundleName; + return loggerBundle.resourceBundleName; } /** @@ -710,8 +746,9 @@ // resource bundle and then call "void log(LogRecord)". private void doLog(LogRecord lr) { lr.setLoggerName(name); - final ResourceBundle bundle = getEffectiveResourceBundle(); - final String ebname = getEffectiveResourceBundleName(); + final LoggerBundle lb = getEffectiveLoggerBundle(); + final ResourceBundle bundle = lb.userBundle; + final String ebname = lb.resourceBundleName; if (ebname != null && bundle != null) { lr.setResourceBundleName(ebname); lr.setResourceBundle(bundle); @@ -1757,8 +1794,6 @@ return useParentHandlers; } - static final String SYSTEM_LOGGER_RB_NAME = "sun.util.logging.resources.logging"; - private static ResourceBundle findSystemResourceBundle(final Locale locale) { // the resource bundle is in a restricted package return AccessController.doPrivileged(new PrivilegedAction() { @@ -1801,11 +1836,12 @@ } Locale currentLocale = Locale.getDefault(); + final LoggerBundle lb = loggerBundle; // Normally we should hit on our simple one entry cache. - if (userBundle != null && - name.equals(resourceBundleName)) { - return userBundle; + if (lb.userBundle != null && + name.equals(lb.resourceBundleName)) { + return lb.userBundle; } else if (catalog != null && currentLocale.equals(catalogLocale) && name.equals(catalogName)) { return catalog; @@ -1864,17 +1900,18 @@ // Synchronized to prevent races in setting the fields. private synchronized void setupResourceInfo(String name, Class callersClass) { - if (resourceBundleName != null) { + final LoggerBundle lb = loggerBundle; + if (lb.resourceBundleName != null) { // this Logger already has a ResourceBundle - if (resourceBundleName.equals(name)) { + if (lb.resourceBundleName.equals(name)) { // the names match so there is nothing more to do return; } // cannot change ResourceBundles once they are set throw new IllegalArgumentException( - resourceBundleName + " != " + name); + lb.resourceBundleName + " != " + name); } if (name == null) { @@ -1890,7 +1927,7 @@ throw new MissingResourceException("Can't find " + name + " bundle", name, ""); } - resourceBundleName = name; + loggerBundle = LoggerBundle.get(name, lb.userBundle); } /** @@ -1920,16 +1957,16 @@ } synchronized (this) { - final boolean canReplaceResourceBundle = resourceBundleName == null - || resourceBundleName.equals(baseName); + LoggerBundle lb = loggerBundle; + final boolean canReplaceResourceBundle = lb.resourceBundleName == null + || lb.resourceBundleName.equals(baseName); if (!canReplaceResourceBundle) { throw new IllegalArgumentException("can't replace resource bundle"); } - userBundle = bundle; - resourceBundleName = baseName; + loggerBundle = LoggerBundle.get(baseName, bundle); } } @@ -2082,45 +2119,53 @@ // Private method to get the potentially inherited - // resource bundle name for this Logger. - // May return null - private String getEffectiveResourceBundleName() { - Logger target = this; - while (target != null) { - String rbn = target.getResourceBundleName(); - if (rbn != null) { - return rbn; + // resource bundle and resource bundle name for this Logger. + // This method never returns null. + private LoggerBundle getEffectiveLoggerBundle() { + final LoggerBundle lb = loggerBundle; + if (lb.isSystemBundle()) { + return SYSTEM_BUNDLE; + } + + // first take care of this logger + final ResourceBundle b = getResourceBundle(); + if (b != null && b == lb.userBundle) { + return lb; + } else if (b != null) { + // either lb.userBundle is null or getResourceBundle() is + // overriden + final String rbName = getResourceBundleName(); + if (!SYSTEM_LOGGER_RB_NAME.equals(rbName) + && !SYSTEM_LOGGER_RB_NAME.equals(b.getBaseBundleName())) { + return LoggerBundle.get(rbName, b); + } else { + return SYSTEM_BUNDLE; } - target = target.getParent(); - } - return null; - } - - - private ResourceBundle getEffectiveResourceBundle() { - Logger target = this; - if (SYSTEM_LOGGER_RB_NAME.equals(resourceBundleName)) return null; - ResourceBundle localRB = getResourceBundle(); - if (localRB != null) { - return localRB; } + // no resource bundle was specified on this logger, look up the + // parent stack. + Logger target = this.parent; while (target != null) { - final ResourceBundle rb = target.userBundle; - if (rb != null) { - return rb; + final LoggerBundle trb = target.loggerBundle; + if (trb.isSystemBundle()) { + return SYSTEM_BUNDLE; + } + if (trb.userBundle != null) { + return trb; } - final String rbn = target.getResourceBundleName(); - if (rbn != null) { - if (!SYSTEM_LOGGER_RB_NAME.equals(rbn)) { - return findResourceBundle(rbn, true); + final String rbName = target.getResourceBundleName(); + if (rbName != null) { + if (!SYSTEM_LOGGER_RB_NAME.equals(rbName)) { + return LoggerBundle.get(rbName, + findResourceBundle(rbName, true)); } else { - return null; + return SYSTEM_BUNDLE; } } target = target.getParent(); } - return null; + return NO_RESOURCE_BUNDLE; } }