
Author: ceki Date: Fri Nov 7 17:00:40 2008 New Revision: 1953 Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/jmx/JMXConfigurator.java logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/jmx/MBeanUtil.java logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/JMXConfiguratorAction.java Log: Add support for a suffix attribute so as to distinguish the JMXConfigurator mbean of different web-application. This feature was requested in LBCLASSIC-61. If you have two web-apps, minimal and minimal other, the logback.xml config files relative to jmxConfigurator would look like: <configuration> <jmxConfigurator suffix="Webapp=minimal" /> ... </configuration> for the "minimal" web-app, and <configuration> <jmxConfigurator suffix="Webapp=minimalOther" /> ... </configuration> for the other web-app. You can choose other values for the suffix contents if you wish. For example, <jmxConfigurator suffix="Fruit=banana" /> is perfectly valid. To help with garbage collection, JMXConfigurator now will clear most if its internal fields. This is not strictly necessary but still helps with GC. Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/jmx/JMXConfigurator.java ============================================================================== --- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/jmx/JMXConfigurator.java (original) +++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/jmx/JMXConfigurator.java Fri Nov 7 17:00:40 2008 @@ -52,29 +52,34 @@ private static String EMPTY = ""; - final LoggerContext loggerContext; - final MBeanServer mbs; - final ObjectName objectName; - + LoggerContext loggerContext; + MBeanServer mbs; + ObjectName objectName; + String objectNameAsString; + + boolean started; @Override - protected void finalize() { - System.out.println("**************** JMXConfigurator finalized"); + public void finalize() { + System.out.println("....... finalize() "+this); } public JMXConfigurator(LoggerContext loggerContext, MBeanServer mbs, ObjectName objectName) { + System.out.println("....... constructor() "+this); + started = true; this.context = loggerContext; this.loggerContext = loggerContext; this.mbs = mbs; this.objectName = objectName; + this.objectNameAsString = objectName.toString(); removePreviousInstanceAsListener(); loggerContext.addListener(this); + } private void removePreviousInstanceAsListener() { List<LoggerContextListener> lcll = loggerContext.getCopyOfListenerList(); - for (LoggerContextListener lcl : lcll) { if (lcl instanceof JMXConfigurator) { JMXConfigurator jmxConfigurator = (JMXConfigurator) lcl; @@ -132,7 +137,6 @@ configurator.doConfigure(url); addInfo("Context: " + loggerContext.getName() + " reloaded."); } finally { - System.out.println("*************** printing"); StatusPrinter.print(statusListenerAsList.getStatusList()); } } @@ -219,30 +223,46 @@ * unregistered */ public void onReset(LoggerContext context) { + if(!started) { + addInfo("onReset() method called on a stopped JMXActivator [" + objectNameAsString + "]");; + } System.out.println("Unregistering JMXConfigurator"); + if (mbs.isRegistered(objectName)) { try { - addInfo("Unregistering mbean [" + objectName + "]"); + addInfo("Unregistering mbean [" + objectNameAsString + "]"); mbs.unregisterMBean(objectName); } catch (InstanceNotFoundException e) { // this is theoretically impossible - addError("Unable to find a verifiably registered mbean [" + objectName + addError("Unable to find a verifiably registered mbean [" + objectNameAsString + "]", e); } catch (MBeanRegistrationException e) { - addError("Failed to unregister [" + objectName + "]", e); + addError("Failed to unregister [" + objectNameAsString + "]", e); } } else { - addInfo("mbean [" + objectName + addInfo("mbean [" + objectNameAsString + "] was not in the mbean registry. This is OK."); } - + stop(); + } + + private void clearFields() { + System.out.println("Clearing fields"); + mbs = null; + objectName = null; + loggerContext = null; } + private void stop() { + started = false; + clearFields(); + } public void onStart(LoggerContext context) { + // nop } - @Override - public String toString() { - return this.getClass().getName() + "(" + context.getName() + ")"; - } +// @Override +// public String toString() { +// return this.getClass().getName() + "(" + context.getName() + ")"; +// } } Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/jmx/MBeanUtil.java ============================================================================== --- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/jmx/MBeanUtil.java (original) +++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/jmx/MBeanUtil.java Fri Nov 7 17:00:40 2008 @@ -51,8 +51,8 @@ try { MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); - JMXConfigurator jmxConfigurator = new JMXConfigurator(loggerContext, - mbs, objectName); + JMXConfigurator jmxConfigurator = new JMXConfigurator(loggerContext, mbs, + objectName); if (mbs.isRegistered(objectName)) { StatusUtil.addWarn(loggerContext, caller, @@ -67,11 +67,6 @@ return null; } } - - - - - public static void unregister(LoggerContext loggerContext, MBeanServer mbs, ObjectName objectName, Object caller) { @@ -82,10 +77,12 @@ mbs.unregisterMBean(objectName); } catch (InstanceNotFoundException e) { // this is theoretically impossible - e.printStackTrace(); + StatusUtil.addError(loggerContext, caller, "Failed to unregister mbean" + + objectName, e); } catch (MBeanRegistrationException e) { - // this also is theoretically impossible - e.printStackTrace(); + // this is theoretically impossible + StatusUtil.addError(loggerContext, caller, "Failed to unregister mbean" + + objectName, e); } } else { StatusUtil.addInfo(loggerContext, caller, "mbean [" + objectName Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/JMXConfiguratorAction.java ============================================================================== --- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/JMXConfiguratorAction.java (original) +++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/JMXConfiguratorAction.java Fri Nov 7 17:00:40 2008 @@ -14,8 +14,10 @@ public class JMXConfiguratorAction extends Action { - static String OBJECT_NAME_ATTRIBUTE_NAME = "objectName"; - + static final String OBJECT_NAME_ATTRIBUTE_NAME = "objectName"; + static final String SUFFIX_ATTRIBUTE_NAME = "suffix"; + static final char JMX_NAME_SEPARATOR = ','; + @Override public void begin(InterpretationContext ec, String name, Attributes attributes) throws ActionException { @@ -24,6 +26,9 @@ String objectNameAsStr; String objectNameAttributeVal = attributes .getValue(OBJECT_NAME_ATTRIBUTE_NAME); + String suffixAttributeVal = attributes + .getValue(SUFFIX_ATTRIBUTE_NAME); + if (OptionHelper.isEmpty(objectNameAttributeVal)) { objectNameAsStr = MBeanUtil.getObjectNameFor((LoggerContext) context, JMXConfigurator.class); @@ -31,6 +36,13 @@ objectNameAsStr = objectNameAttributeVal; } + if(!OptionHelper.isEmpty(suffixAttributeVal)) { + if(suffixAttributeVal.indexOf(0) != JMX_NAME_SEPARATOR) { + objectNameAsStr += JMX_NAME_SEPARATOR; + } + objectNameAsStr += suffixAttributeVal; + } + ObjectName objectName = MBeanUtil.string2ObjectName(context, this, objectNameAsStr);