Index: java/org/apache/juli/ClassLoaderLogManager.java =================================================================== --- java/org/apache/juli/ClassLoaderLogManager.java (revision 1004057) +++ java/org/apache/juli/ClassLoaderLogManager.java (working copy) @@ -124,84 +124,15 @@ final String loggerName = logger.getName(); - ClassLoader classLoader = - Thread.currentThread().getContextClassLoader(); - ClassLoaderLogInfo info = getClassLoaderInfo(classLoader); + ClassLoaderLogInfo info = + getClassLoaderInfo(Thread.currentThread().getContextClassLoader()); + if (info.loggers.containsKey(loggerName)) { return false; } info.loggers.put(loggerName, logger); - // Apply initial level for new logger - final String levelString = getProperty(loggerName + ".level"); - if (levelString != null) { - try { - AccessController.doPrivileged(new PrivilegedAction() { - @Override - public Void run() { - logger.setLevel(Level.parse(levelString.trim())); - return null; - } - }); - } catch (IllegalArgumentException e) { - // Leave level set to null - } - } - - // Always instantiate parent loggers so that - // we can control log categories even during runtime - int dotIndex = loggerName.lastIndexOf('.'); - if (dotIndex >= 0) { - final String parentName = loggerName.substring(0, dotIndex); - Logger.getLogger(parentName); - } - - // Find associated node - LogNode node = info.rootNode.findNode(loggerName); - node.logger = logger; - - // Set parent logger - Logger parentLogger = node.findParentLogger(); - if (parentLogger != null) { - doSetParentLogger(logger, parentLogger); - } - - // Tell children we are their new parent - node.setParentLogger(logger); - - // Add associated handlers, if any are defined using the .handlers property. - // In this case, handlers of the parent logger(s) will not be used - String handlers = getProperty(loggerName + ".handlers"); - if (handlers != null) { - logger.setUseParentHandlers(false); - StringTokenizer tok = new StringTokenizer(handlers, ","); - while (tok.hasMoreTokens()) { - String handlerName = (tok.nextToken().trim()); - Handler handler = null; - ClassLoader current = classLoader; - while (current != null) { - info = classLoaderLoggers.get(current); - if (info != null) { - handler = info.handlers.get(handlerName); - if (handler != null) { - break; - } - } - current = current.getParent(); - } - if (handler != null) { - logger.addHandler(handler); - } - } - } - - // Parse useParentHandlers to set if the logger should delegate to its parent. - // Unlike java.util.logging, the default is to not delegate if a list of handlers - // has been specified for the logger. - String useParentHandlersString = getProperty(loggerName + ".useParentHandlers"); - if (Boolean.valueOf(useParentHandlersString).booleanValue()) { - logger.setUseParentHandlers(true); - } + initLogger(info, logger); return true; } @@ -294,7 +225,6 @@ throws IOException, SecurityException { checkAccess(); - reset(); readConfiguration(is, Thread.currentThread().getContextClassLoader()); @@ -311,6 +241,9 @@ } ClassLoader classLoader = thread.getContextClassLoader(); ClassLoaderLogInfo clLogInfo = getClassLoaderInfo(classLoader); + + // super class properties are also reset + clLogInfo.props.clear(); resetLoggers(clLogInfo); super.reset(); } @@ -340,6 +273,10 @@ for (Handler handler : handlers) { logger.removeHandler(handler); } + // reset level in case a new handler is attached later + // since static references to loggers may exist we DO NOT + // want to remove the logger from ClassLoaderLogInfo + logger.setLevel(null); } for (Handler handler : clLogInfo.handlers.values()) { try { @@ -476,8 +413,10 @@ * @throws IOException If something wrong happens during loading */ protected void readConfiguration(InputStream is, ClassLoader classLoader) - throws IOException { + throws IOException { + reset(); + ClassLoaderLogInfo info = classLoaderLoggers.get(classLoader); try { @@ -536,7 +475,7 @@ } } - + initializeAvailableLoggers(info); } @@ -586,6 +525,121 @@ } + /** + * Based on the pre-created logger, initialize it with relevant settings. + * + * @param info + * @param logger + */ + private void initLogger(ClassLoaderLogInfo info, final Logger logger) { + + String loggerName = logger.getName(); + + // Apply initial level for new logger + final String levelString = getProperty(loggerName + ".level"); + if (levelString != null) { + try { + AccessController.doPrivileged(new PrivilegedAction() { + @Override + public Void run() { + logger.setLevel(Level.parse(levelString.trim())); + return null; + } + }); + } catch (IllegalArgumentException e) { + // Leave level set to null + } + } + + // Always instantiate parent loggers so that + // we can control log categories even during runtime + int dotIndex = loggerName.lastIndexOf('.'); + if (dotIndex >= 0) { + final String parentName = loggerName.substring(0, dotIndex); + Logger.getLogger(parentName); + } + + // Find associated node + LogNode node = info.rootNode.findNode(loggerName); + node.logger = logger; + + // Set parent logger + Logger parentLogger = node.findParentLogger(); + if (parentLogger != null) { + doSetParentLogger(logger, parentLogger); + } + + // Tell children we are their new parent + node.setParentLogger(logger); + + // Add associated handlers, if any are defined using the .handlers property. + // In this case, handlers of the parent logger(s) will not be used + String handlers = getProperty(loggerName + ".handlers"); + if (handlers != null) { + logger.setUseParentHandlers(false); + StringTokenizer tok = new StringTokenizer(handlers, ","); + while (tok.hasMoreTokens()) { + String handlerName = (tok.nextToken().trim()); + Handler handler = null; + ClassLoader current = + Thread.currentThread().getContextClassLoader(); + while (current != null) { + info = classLoaderLoggers.get(current); + if (info != null) { + handler = info.handlers.get(handlerName); + if (handler != null) { + break; + } + } + current = current.getParent(); + } + if (handler != null) { + logger.addHandler(handler); + } + } + } + + // Parse useParentHandlers to set if the logger should delegate to its parent. + // Unlike java.util.logging, the default is to not delegate if a list of handlers + // has been specified for the logger. + String useParentHandlersString = getProperty(loggerName + ".useParentHandlers"); + if (Boolean.valueOf(useParentHandlersString).booleanValue()) { + logger.setUseParentHandlers(true); + } + } + + + /** + * Whether it is initial configuration and any time the configuration is + * reread, initialize all the loggers based on the current configuration + * property state if loggers are already added. + * + * @param info + */ + private void initializeAvailableLoggers(ClassLoaderLogInfo info) { + Enumeration enumeration = info.props.propertyNames(); + Logger logger = null; + String name = null; + String key = null; + + while (enumeration.hasMoreElements()) { + key = (String)enumeration.nextElement(); + if (!key.endsWith(".level")) { + continue; + } + name = key.substring(0, key.length() - 6); + logger = getLogger(name); + if (logger == null) { + // not loaded + continue; + } + + // re-initialize loggers already loaded + initLogger(info, logger); + } + } + + // ---------------------------------------------------- LogNode Inner Class