Author: markt Date: Mon May 3 21:40:52 2010 New Revision: 940634 URL: http://svn.apache.org/viewvc?rev=940634&view=rev Log: With the benefit of some sleep, refactor the MBean support for Lifecycle (still some components to convert) Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=49134 Thanks to Marc Guillemot whose test case for 49134 provided the basis of o.a.c.mbeans.TestRegistration
Added: tomcat/trunk/java/org/apache/catalina/util/LifecycleMBeanBase.java (with props) tomcat/trunk/test/org/apache/catalina/mbeans/TestRegistration.java - copied, changed from r940487, tomcat/trunk/test/org/apache/catalina/mbeans/RegistrationTest.java Removed: tomcat/trunk/java/org/apache/catalina/LifecycleMBeanRegistration.java tomcat/trunk/test/org/apache/catalina/mbeans/RegistrationTest.java Modified: tomcat/trunk/java/org/apache/catalina/connector/Connector.java tomcat/trunk/java/org/apache/catalina/core/StandardContext.java tomcat/trunk/java/org/apache/catalina/core/StandardServer.java tomcat/trunk/java/org/apache/catalina/core/StandardService.java tomcat/trunk/java/org/apache/catalina/core/StandardThreadExecutor.java tomcat/trunk/java/org/apache/catalina/loader/WebappLoader.java tomcat/trunk/java/org/apache/catalina/mbeans/MBeanFactory.java tomcat/trunk/java/org/apache/catalina/mbeans/MBeanUtils.java tomcat/trunk/java/org/apache/catalina/startup/Tomcat.java tomcat/trunk/java/org/apache/catalina/util/LifecycleBase.java tomcat/trunk/java/org/apache/catalina/util/LocalStrings.properties tomcat/trunk/java/org/apache/coyote/http11/Http11Protocol.java tomcat/trunk/test/org/apache/catalina/startup/TomcatBaseTest.java Modified: tomcat/trunk/java/org/apache/catalina/connector/Connector.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/Connector.java?rev=940634&r1=940633&r2=940634&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/connector/Connector.java (original) +++ tomcat/trunk/java/org/apache/catalina/connector/Connector.java Mon May 3 21:40:52 2010 @@ -20,16 +20,14 @@ package org.apache.catalina.connector; import java.util.HashMap; -import javax.management.MBeanRegistration; -import javax.management.MBeanServer; -import javax.management.MalformedObjectNameException; import javax.management.ObjectName; import org.apache.catalina.LifecycleException; import org.apache.catalina.LifecycleState; import org.apache.catalina.Service; import org.apache.catalina.core.AprLifecycleListener; -import org.apache.catalina.util.LifecycleBase; +import org.apache.catalina.mbeans.MBeanUtils; +import org.apache.catalina.util.LifecycleMBeanBase; import org.apache.tomcat.util.res.StringManager; import org.apache.coyote.Adapter; import org.apache.coyote.ProtocolHandler; @@ -37,7 +35,6 @@ import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; import org.apache.tomcat.util.IntrospectionUtils; import org.apache.tomcat.util.http.mapper.Mapper; -import org.apache.tomcat.util.modeler.Registry; /** @@ -49,7 +46,7 @@ import org.apache.tomcat.util.modeler.Re */ -public class Connector extends LifecycleBase implements MBeanRegistration { +public class Connector extends LifecycleMBeanBase { private static final Log log = LogFactory.getLog(Connector.class); @@ -796,12 +793,11 @@ public class Connector extends Lifecycle } - protected ObjectName createObjectName(String domain, String type) - throws MalformedObjectNameException { + protected String createObjectNameKeyProperties(String type) { + Object addressObj = getProperty("address"); - StringBuilder sb = new StringBuilder(domain); - sb.append(":type="); + StringBuilder sb = new StringBuilder("type="); sb.append(type); sb.append(",port="); sb.append(getPort()); @@ -812,8 +808,7 @@ public class Connector extends Lifecycle sb.append(ObjectName.quote(address)); } } - ObjectName _oname = new ObjectName(sb.toString()); - return _oname; + return sb.toString(); } @@ -843,6 +838,37 @@ public class Connector extends Lifecycle } + @Override + protected void initInternal() throws LifecycleException { + + super.initInternal(); + + // Initialize adapter + adapter = new CoyoteAdapter(this); + protocolHandler.setAdapter(adapter); + + IntrospectionUtils.setProperty(protocolHandler, "jkHome", + System.getProperty("catalina.base")); + + try { + protocolHandler.init(); + } catch (Exception e) { + throw new LifecycleException + (sm.getString + ("coyoteConnector.protocolHandlerInitializationFailed", e)); + } + + onameProtocolHandler = register(protocolHandler, + createObjectNameKeyProperties("ProtocolHandler")); + + mapperListener.setDomain(getDomain()); + mapperListener.init(); + + onameMapper = register(mapperListener, + createObjectNameKeyProperties("Mapper")); + } + + /** * Begin processing requests via this Connector. * @@ -853,23 +879,6 @@ public class Connector extends Lifecycle setState(LifecycleState.STARTING); - // We can't register earlier - the JMX registration of this happens - // in Server.start callback - if ( this.oname != null ) { - // We are registred - register the adapter as well. - try { - Registry.getRegistry(null, null).registerComponent - (protocolHandler, createObjectName(this.domain,"ProtocolHandler"), null); - } catch (Exception ex) { - log.error(sm.getString - ("coyoteConnector.protocolRegistrationFailed"), ex); - } - } else { - if(log.isInfoEnabled()) - log.info(sm.getString - ("coyoteConnector.cannotRegisterProtocol")); - } - try { protocolHandler.start(); } catch (Exception e) { @@ -882,23 +891,6 @@ public class Connector extends Lifecycle (errPrefix + " " + sm.getString ("coyoteConnector.protocolHandlerStartFailed", e)); } - - if( this.domain != null ) { - mapperListener.setDomain( domain ); - //mapperListener.setEngine( service.getContainer().getName() ); - mapperListener.init(); - try { - ObjectName mapperOname = createObjectName(this.domain,"Mapper"); - if (log.isDebugEnabled()) - log.debug(sm.getString( - "coyoteConnector.MapperRegistration", mapperOname)); - Registry.getRegistry(null, null).registerComponent - (mapper, mapperOname, "Mapper"); - } catch (Exception ex) { - log.error(sm.getString - ("coyoteConnector.protocolRegistrationFailed"), ex); - } - } } @@ -912,16 +904,15 @@ public class Connector extends Lifecycle setState(LifecycleState.STOPPING); - try { - mapperListener.destroy(); - Registry.getRegistry(null, null).unregisterComponent - (createObjectName(this.domain,"Mapper")); - Registry.getRegistry(null, null).unregisterComponent - (createObjectName(this.domain,"ProtocolHandler")); - } catch (MalformedObjectNameException e) { - log.error( sm.getString - ("coyoteConnector.protocolUnregistrationFailed"), e); - } + } + + + @Override + protected void destroyInternal() throws LifecycleException { + mapperListener.destroy(); + unregister(onameMapper); + unregister(onameProtocolHandler); + try { protocolHandler.destroy(); } catch (Exception e) { @@ -930,6 +921,11 @@ public class Connector extends Lifecycle ("coyoteConnector.protocolHandlerDestroyFailed", e)); } + if (getService() != null) { + getService().removeConnector(this); + } + + super.destroyInternal(); } @@ -948,92 +944,19 @@ public class Connector extends Lifecycle return sb.toString(); } - // -------------------- JMX registration -------------------- - protected String domain; - protected ObjectName oname; - protected MBeanServer mserver; - - public ObjectName getObjectName() { - return oname; - } - - public String getDomain() { - return domain; - } - - public ObjectName preRegister(MBeanServer server, - ObjectName name) throws Exception { - oname=name; - mserver=server; - domain=name.getDomain(); - return name; - } - - public void postRegister(Boolean registrationDone) { - // NOOP - } - - public void preDeregister() throws Exception { - // NOOP - } - - public void postDeregister() { - try { - if(getState().isAvailable()) { - stop(); - } - } catch( Throwable t ) { - log.error( "Unregistering - can't stop", t); - } - } - + private ObjectName onameProtocolHandler; + private ObjectName onameMapper; + @Override - protected void initInternal() throws LifecycleException { - - if (oname == null) { - try { - // we are loaded directly, via API - and no name was given to us - // Engine name is used as domain name for MBeans - oname = createObjectName( - getService().getContainer().getName(), "Connector"); - Registry.getRegistry(null, null) - .registerComponent(this, oname, null); - } catch (Exception e) { - log.error( "Error registering connector ", e); - } - if(log.isDebugEnabled()) - log.debug("Creating name for connector " + oname); - } - - // Initializa adapter - adapter = new CoyoteAdapter(this); - protocolHandler.setAdapter(adapter); - - IntrospectionUtils.setProperty(protocolHandler, "jkHome", - System.getProperty("catalina.base")); - - try { - protocolHandler.init(); - } catch (Exception e) { - throw new LifecycleException - (sm.getString - ("coyoteConnector.protocolHandlerInitializationFailed", e)); - } - + protected String getDomainInternal() { + return MBeanUtils.getDomain(getService()); } @Override - protected void destroyInternal() { - if (oname!=null) { - if(log.isDebugEnabled()) - log.debug("Unregister itself " + oname ); - Registry.getRegistry(null, null).unregisterComponent(oname); - } - if( getService() == null) - return; - getService().removeConnector(this); + protected String getObjectNameKeyProperties() { + return createObjectNameKeyProperties("Connector"); } } Modified: tomcat/trunk/java/org/apache/catalina/core/StandardContext.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/StandardContext.java?rev=940634&r1=940633&r2=940634&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/core/StandardContext.java (original) +++ tomcat/trunk/java/org/apache/catalina/core/StandardContext.java Mon May 3 21:40:52 2010 @@ -5014,6 +5014,23 @@ public class StandardContext */ @Override protected void destroyInternal() throws LifecycleException { + + if ((manager != null) && (manager instanceof Lifecycle)) { + ((Lifecycle) manager).destroy(); + } + if ((realm != null) && (realm instanceof Lifecycle)) { + ((Lifecycle) realm).destroy(); + } + if ((cluster != null) && (cluster instanceof Lifecycle)) { + ((Lifecycle) cluster).destroy(); + } + if ((logger != null) && (logger instanceof Lifecycle)) { + ((Lifecycle) logger).destroy(); + } + if ((loader != null) && (loader instanceof Lifecycle)) { + ((Lifecycle) loader).destroy(); + } + if( oname != null ) { // Send j2ee.object.deleted notification Notification notification = @@ -5029,7 +5046,6 @@ public class StandardContext synchronized (instanceListenersLock) { instanceListeners = new String[0]; } - } private void resetContext() throws Exception { Modified: tomcat/trunk/java/org/apache/catalina/core/StandardServer.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/StandardServer.java?rev=940634&r1=940633&r2=940634&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/core/StandardServer.java (original) +++ tomcat/trunk/java/org/apache/catalina/core/StandardServer.java Mon May 3 21:40:52 2010 @@ -29,27 +29,24 @@ import java.net.Socket; import java.security.AccessControlException; import java.util.Random; -import javax.management.MBeanServer; -import javax.management.MalformedObjectNameException; import javax.management.ObjectName; import org.apache.catalina.Container; import org.apache.catalina.Context; -import org.apache.catalina.Globals; import org.apache.catalina.LifecycleException; -import org.apache.catalina.LifecycleMBeanRegistration; import org.apache.catalina.LifecycleState; import org.apache.catalina.Server; import org.apache.catalina.Service; import org.apache.catalina.deploy.NamingResources; import org.apache.catalina.mbeans.MBeanFactory; +import org.apache.catalina.mbeans.MBeanUtils; import org.apache.catalina.util.LifecycleBase; +import org.apache.catalina.util.LifecycleMBeanBase; import org.apache.tomcat.util.res.StringManager; import org.apache.catalina.util.ServerInfo; import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; import org.apache.tomcat.util.buf.StringCache; -import org.apache.tomcat.util.modeler.Registry; /** @@ -59,8 +56,8 @@ import org.apache.tomcat.util.modeler.Re * @author Craig R. McClanahan * @version $Id$ */ -public final class StandardServer extends LifecycleBase - implements Server, LifecycleMBeanRegistration { +public final class StandardServer extends LifecycleMBeanBase + implements Server { private static final Log log = LogFactory.getLog(StandardServer.class); @@ -684,29 +681,17 @@ public final class StandardServer extend */ @Override protected void initInternal() throws LifecycleException { + + super.initInternal(); // Register global String cache // Note although the cache is global, if there are multiple Servers // present in the JVM (may happen when embedding) then the same cache // will be registered under multiple names - try { - onameStringCache = - new ObjectName(oname.getDomain() + ":type=StringCache"); - Registry.getRegistry(null, null) - .registerComponent(new StringCache(), onameStringCache, null); - } catch (Exception e) { - log.error("Error registering ",e); - } + onameStringCache = register(new StringCache(), "type=StringCache"); // Register the MBeanFactory - try { - onameMBeanFactory = - new ObjectName(oname.getDomain() + ":type=MBeanFactory"); - Registry.getRegistry(null, null) - .registerComponent(new MBeanFactory(), onameMBeanFactory, null); - } catch (Exception e) { - log.error("Error registering ",e); - } + onameMBeanFactory = register(new MBeanFactory(), "type=MBeanFactory"); // Initialize our defined Services for (int i = 0; i < services.length; i++) { @@ -716,24 +701,18 @@ public final class StandardServer extend @Override protected void destroyInternal() throws LifecycleException { - Registry registry = Registry.getRegistry(null, null); - - if (onameStringCache != null) { - registry.unregisterComponent(onameStringCache); - } - if (onameMBeanFactory != null) { - registry.unregisterComponent(onameMBeanFactory); - } - // Destroy our defined Services for (int i = 0; i < services.length; i++) { services[i].destroy(); } + + unregister(onameMBeanFactory); + + unregister(onameStringCache); + + super.destroyInternal(); } - protected volatile String domain; - protected volatile ObjectName oname; - protected MBeanServer mserver; private ObjectName onameStringCache; private ObjectName onameMBeanFactory; @@ -743,72 +722,27 @@ public final class StandardServer extend * <ol> * <li>Name of first {...@link Engine}.</li> * <li>Name of first {...@link Service}.</li> - * <li>Global default defined by {...@link Globals#DEFAULT_MBEAN_DOMAIN}</li> * </ol> */ - public String getDomain() { - if (domain == null) { - Service[] services = findServices(); - if (services.length > 0) { - Service service = services[0]; - if (service != null) { - Container container = service.getContainer(); - if (container != null) { - domain = container.getName(); - } else { - domain = service.getName(); - } - } - } - if (domain == null) { - domain = Globals.DEFAULT_MBEAN_DOMAIN; + @Override + protected String getDomainInternal() { + + String domain = null; + + Service[] services = findServices(); + if (services.length > 0) { + Service service = services[0]; + if (service != null) { + domain = MBeanUtils.getDomain(service); } } return domain; } - public void setDomain(String domain) { - this.domain = domain; - } - - - public ObjectName getObjectName() { - if (oname == null) { - StringBuilder name = new StringBuilder(getDomain()); - name.append(":type=Server"); - - try { - oname = new ObjectName(name.toString()); - } catch (MalformedObjectNameException e) { - log.warn(sm.getString("standardServer.onameFail", name), e); - } catch (NullPointerException e) { - // Never going to happen - } - } - - return oname; - } - - - public ObjectName preRegister(MBeanServer server, - ObjectName name) throws Exception { - oname = name; - mserver = server; - domain = name.getDomain(); - return name; - } - - public void postRegister(Boolean registrationDone) { - // NOOP - } - - public void preDeregister() throws Exception { - // NOOP + @Override + protected final String getObjectNameKeyProperties() { + return "type=Server"; } - public void postDeregister() { - // NOOP - } - } Modified: tomcat/trunk/java/org/apache/catalina/core/StandardService.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/StandardService.java?rev=940634&r1=940633&r2=940634&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/core/StandardService.java (original) +++ tomcat/trunk/java/org/apache/catalina/core/StandardService.java Mon May 3 21:40:52 2010 @@ -21,24 +21,21 @@ package org.apache.catalina.core; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; -import javax.management.MBeanServer; -import javax.management.MalformedObjectNameException; import javax.management.ObjectName; import org.apache.catalina.Container; import org.apache.catalina.Engine; -import org.apache.catalina.Globals; import org.apache.catalina.Lifecycle; import org.apache.catalina.LifecycleException; -import org.apache.catalina.LifecycleMBeanRegistration; import org.apache.catalina.LifecycleState; import org.apache.catalina.Server; import org.apache.catalina.Service; import org.apache.catalina.connector.Connector; +import org.apache.catalina.mbeans.MBeanUtils; import org.apache.catalina.util.LifecycleBase; +import org.apache.catalina.util.LifecycleMBeanBase; import org.apache.tomcat.util.res.StringManager; import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; -import org.apache.tomcat.util.modeler.Registry; import java.util.ArrayList; import org.apache.catalina.Executor; @@ -51,8 +48,7 @@ import org.apache.catalina.Executor; * @author Craig R. McClanahan */ -public class StandardService extends LifecycleBase - implements Service, LifecycleMBeanRegistration { +public class StandardService extends LifecycleMBeanBase implements Service { private static final Log log = LogFactory.getLog(StandardService.class); @@ -509,14 +505,16 @@ public class StandardService extends Lif @Override protected void initInternal() throws LifecycleException { + super.initInternal(); + if (container != null) { container.init(); } // Initialize any Executors for (Executor executor : findExecutors()) { - if (executor instanceof LifecycleMBeanRegistration) { - ((LifecycleMBeanRegistration) executor).setDomain(getDomain()); + if (executor instanceof LifecycleMBeanBase) { + ((LifecycleMBeanBase) executor).setDomain(getDomain()); } executor.init(); } @@ -537,8 +535,6 @@ public class StandardService extends Lif @Override protected void destroyInternal() throws LifecycleException { - Registry.getRegistry(null, null).unregisterComponent(oname); - // Destroy our defined Connectors synchronized (connectors) { for (Connector connector : connectors) { @@ -561,72 +557,17 @@ public class StandardService extends Lif container.destroy(); } + super.destroyInternal(); } - protected volatile String domain; - protected volatile ObjectName oname; - - /** - * Obtain the MBean domain for this server. The domain is obtained using - * the following search order: - * <ol> - * <li>Name of the {...@link Engine}.</li> - * <li>Name of the {...@link Service}.</li> - * <li>Global default defined by {...@link Globals#DEFAULT_MBEAN_DOMAIN}</li> - * </ol> - */ - public String getDomain() { - if (domain == null) { - Container container = getContainer(); - if (container != null) { - domain = container.getName(); - } else { - domain = getName(); - } - if (domain == null) { - domain = Globals.DEFAULT_MBEAN_DOMAIN; - } - } - return domain; - } - - public void setDomain(String domain) { - this.domain = domain; - } - - public ObjectName getObjectName() { - if (oname == null) { - StringBuilder name = new StringBuilder(getDomain()); - name.append(":type=Service"); - - try { - oname = new ObjectName(name.toString()); - } catch (MalformedObjectNameException e) { - log.warn(sm.getString("standardService.onameFail", name), e); - } catch (NullPointerException e) { - // Never going to happen - } - } + @Override + protected String getDomainInternal() { - return oname; - } - public ObjectName preRegister(MBeanServer server, - ObjectName name) throws Exception { - oname=name; - domain=name.getDomain(); - return name; + return MBeanUtils.getDomain(this); } - public void postRegister(Boolean registrationDone) { - // NOOP - } - - public void preDeregister() throws Exception { - // NOOP - } - - public void postDeregister() { - // NOOP + @Override + public final String getObjectNameKeyProperties() { + return "type=Service"; } - } Modified: tomcat/trunk/java/org/apache/catalina/core/StandardThreadExecutor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/StandardThreadExecutor.java?rev=940634&r1=940633&r2=940634&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/core/StandardThreadExecutor.java (original) +++ tomcat/trunk/java/org/apache/catalina/core/StandardThreadExecutor.java Mon May 3 21:40:52 2010 @@ -20,35 +20,19 @@ package org.apache.catalina.core; import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.TimeUnit; -import javax.management.MBeanServer; -import javax.management.MalformedObjectNameException; -import javax.management.ObjectName; - import org.apache.catalina.Executor; import org.apache.catalina.LifecycleException; -import org.apache.catalina.LifecycleMBeanRegistration; import org.apache.catalina.LifecycleState; import org.apache.catalina.util.LifecycleBase; -import org.apache.juli.logging.Log; -import org.apache.juli.logging.LogFactory; -import org.apache.tomcat.util.res.StringManager; +import org.apache.catalina.util.LifecycleMBeanBase; import org.apache.tomcat.util.threads.ResizableExecutor; import org.apache.tomcat.util.threads.TaskQueue; import org.apache.tomcat.util.threads.TaskThreadFactory; import org.apache.tomcat.util.threads.ThreadPoolExecutor; -public class StandardThreadExecutor extends LifecycleBase - implements Executor, ResizableExecutor, LifecycleMBeanRegistration { - - private static final Log log = - LogFactory.getLog(StandardThreadExecutor.class); +public class StandardThreadExecutor extends LifecycleMBeanBase + implements Executor, ResizableExecutor { - /** - * The string manager for this package. - */ - private static final StringManager sm = - StringManager.getManager(Constants.Package); - // ---------------------------------------------- Properties /** * Default thread priority @@ -308,57 +292,16 @@ public class StandardThreadExecutor exte } - protected volatile String domain; - protected volatile ObjectName oname; - - /** - * Obtain the MBean domain for this server. The domain is set by the - * containing Service. - */ - public String getDomain() { - return domain; - } - - public void setDomain(String domain) { - this.domain = domain; - } - - public ObjectName getObjectName() { - if (oname == null) { - StringBuilder name = new StringBuilder(getDomain()); - name.append(":type=Executor,name="); - name.append(getName()); - - try { - oname = new ObjectName(name.toString()); - } catch (MalformedObjectNameException e) { - log.warn(sm.getString( - "standardThreadExecutor.onameFail", name), e); - } catch (NullPointerException e) { - // Never going to happen - } - } - - return oname; - } - - public ObjectName preRegister(MBeanServer server, - ObjectName name) throws Exception { - oname=name; - domain=name.getDomain(); - return name; - } - - public void postRegister(Boolean registrationDone) { - // NOOP - } - - public void preDeregister() throws Exception { - // NOOP + @Override + protected String getDomainInternal() { + // No way to navigate to Engine. Needs to have domain set. + return null; } - public void postDeregister() { - // NOOP + @Override + protected String getObjectNameKeyProperties() { + StringBuilder name = new StringBuilder("type=Executor,name="); + name.append(getName()); + return name.toString(); } - } Modified: tomcat/trunk/java/org/apache/catalina/loader/WebappLoader.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/loader/WebappLoader.java?rev=940634&r1=940633&r2=940634&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/loader/WebappLoader.java (original) +++ tomcat/trunk/java/org/apache/catalina/loader/WebappLoader.java Mon May 3 21:40:52 2010 @@ -37,8 +37,6 @@ import java.net.URLStreamHandlerFactory; import java.util.ArrayList; import java.util.jar.JarFile; -import javax.management.MBeanRegistration; -import javax.management.MBeanServer; import javax.management.ObjectName; import javax.naming.NameClassPair; import javax.naming.NamingEnumeration; @@ -54,7 +52,9 @@ import org.apache.catalina.LifecycleExce import org.apache.catalina.LifecycleState; import org.apache.catalina.Loader; import org.apache.catalina.core.StandardContext; +import org.apache.catalina.mbeans.MBeanUtils; import org.apache.catalina.util.LifecycleBase; +import org.apache.catalina.util.LifecycleMBeanBase; import org.apache.tomcat.util.res.StringManager; import org.apache.naming.resources.DirContextURLStreamHandler; import org.apache.naming.resources.DirContextURLStreamHandlerFactory; @@ -80,8 +80,8 @@ import org.apache.tomcat.util.modeler.Re * @version $Id$ */ -public class WebappLoader extends LifecycleBase - implements Loader, PropertyChangeListener, MBeanRegistration { +public class WebappLoader extends LifecycleMBeanBase + implements Loader, PropertyChangeListener { // ----------------------------------------------------------- Constructors @@ -526,41 +526,6 @@ public class WebappLoader extends Lifecy } - @Override - protected void initInternal() { - - if( oname==null ) { - // not registered yet - standalone or API - if( container instanceof StandardContext) { - // Register ourself. The container must be a webapp - try { - StandardContext ctx=(StandardContext)container; - String path = ctx.getPath(); - if (path.equals("")) { - path = "/"; - } - oname=new ObjectName(ctx.getEngineName() + ":type=Loader,path=" + - path + ",host=" + ctx.getParent().getName()); - Registry.getRegistry(null, null).registerComponent(this, oname, null); - } catch (Exception e) { - log.error("Error registering loader", e ); - } - } - } - - if( container == null ) { - // JMX created the loader - // TODO - - } - } - - @Override - protected void destroyInternal() { - Registry.getRegistry(null, null).unregisterComponent(oname); - oname = null; - } - /** * Start associated {...@link ClassLoader} and implement the requirements * of {...@link LifecycleBase#startInternal()}. @@ -1188,23 +1153,37 @@ public class WebappLoader extends Lifecy private static final org.apache.juli.logging.Log log= org.apache.juli.logging.LogFactory.getLog( WebappLoader.class ); - private ObjectName oname; - public ObjectName preRegister(MBeanServer server, - ObjectName name) throws Exception { - oname=name; - return name; + @Override + protected String getDomainInternal() { + return MBeanUtils.getDomain(container); } - public void postRegister(Boolean registrationDone) { - // NOOP - } - public void preDeregister() throws Exception { - // NOOP + @Override + protected String getObjectNameKeyProperties() { + + StringBuilder name = new StringBuilder("type=Loader"); + + if (container instanceof Context) { + name.append(",path="); + Context context = (Context) container; + + String path = context.getPath(); + if (path.equals("")) { + path = "/"; + } + name.append(path); + + name.append(",host="); + name.append(context.getParent().getName()); + } else { + // Unlikely / impossible? Handle it to be safe + name.append(",container="); + name.append(container.getName()); + } + + return name.toString(); } - public void postDeregister() { - // NOOP - } } Modified: tomcat/trunk/java/org/apache/catalina/mbeans/MBeanFactory.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/mbeans/MBeanFactory.java?rev=940634&r1=940633&r2=940634&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/mbeans/MBeanFactory.java (original) +++ tomcat/trunk/java/org/apache/catalina/mbeans/MBeanFactory.java Mon May 3 21:40:52 2010 @@ -83,11 +83,10 @@ public class MBeanFactory { * @exception RuntimeOperationsException if an IllegalArgumentException * occurs */ - public MBeanFactory() - throws MBeanException, RuntimeOperationsException { + public MBeanFactory() { super(); - + } Modified: tomcat/trunk/java/org/apache/catalina/mbeans/MBeanUtils.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/mbeans/MBeanUtils.java?rev=940634&r1=940633&r2=940634&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/mbeans/MBeanUtils.java (original) +++ tomcat/trunk/java/org/apache/catalina/mbeans/MBeanUtils.java Mon May 3 21:40:52 2010 @@ -1616,4 +1616,62 @@ public class MBeanUtils { } + + /** + * Determine the name of the domain to register MBeans for from a given + * Service. + * + * @param service + * @return + */ + public static String getDomain(Service service) { + + // Null service -> return null + if (service == null) { + return null; + } + + String domain = null; + + Container engine = service.getContainer(); + + // Use the engine name first + if (engine != null) { + domain = engine.getName(); + } + + // No engine or no engine name, use the service name + if (domain == null) { + domain = service.getName(); + } + + // No service name, use null + return domain; + } + + + /** + * Determine the name of the domain to register MBeans for from a given + * Container. + * + * @param container + * @return + */ + public static String getDomain(Container container) { + + String domain = null; + + Container c = container; + + while (!(c instanceof Engine)) { + c = c.getParent(); + } + + if (c instanceof Engine) { + domain = c.getName(); + } + + return domain; + } + } Modified: tomcat/trunk/java/org/apache/catalina/startup/Tomcat.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/startup/Tomcat.java?rev=940634&r1=940633&r2=940634&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/startup/Tomcat.java (original) +++ tomcat/trunk/java/org/apache/catalina/startup/Tomcat.java Mon May 3 21:40:52 2010 @@ -320,7 +320,7 @@ public class Tomcat { public void destroy() throws LifecycleException { getServer(); server.destroy(); - // Could null out obejcts here + // Could null out objects here } /** Modified: tomcat/trunk/java/org/apache/catalina/util/LifecycleBase.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/util/LifecycleBase.java?rev=940634&r1=940633&r2=940634&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/util/LifecycleBase.java (original) +++ tomcat/trunk/java/org/apache/catalina/util/LifecycleBase.java Mon May 3 21:40:52 2010 @@ -17,16 +17,12 @@ package org.apache.catalina.util; -import javax.management.ObjectName; - import org.apache.catalina.Lifecycle; import org.apache.catalina.LifecycleException; import org.apache.catalina.LifecycleListener; -import org.apache.catalina.LifecycleMBeanRegistration; import org.apache.catalina.LifecycleState; import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; -import org.apache.tomcat.util.modeler.Registry; import org.apache.tomcat.util.res.StringManager; @@ -99,20 +95,6 @@ public abstract class LifecycleBase impl invalidTransition(Lifecycle.INIT_EVENT); } - // Register MBean if required - if (this instanceof LifecycleMBeanRegistration) { - ObjectName oname = - ((LifecycleMBeanRegistration) this).getObjectName(); - - try { - Registry.getRegistry(null, null).registerComponent( - this, oname, null); - } catch (Exception e) { - log.warn(sm.getString("lifecycleBase.initMBeanFail", toString(), - oname), e); - } - } - initInternal(); setState(LifecycleState.INITIALIZED); @@ -279,13 +261,6 @@ public abstract class LifecycleBase impl destroyInternal(); - // De-register MBean if required - if (this instanceof LifecycleMBeanRegistration) { - ObjectName oname = - ((LifecycleMBeanRegistration) this).getObjectName(); - Registry.getRegistry(null, null).unregisterComponent(oname); - } - setState(LifecycleState.DESTROYED); } Added: tomcat/trunk/java/org/apache/catalina/util/LifecycleMBeanBase.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/util/LifecycleMBeanBase.java?rev=940634&view=auto ============================================================================== --- tomcat/trunk/java/org/apache/catalina/util/LifecycleMBeanBase.java (added) +++ tomcat/trunk/java/org/apache/catalina/util/LifecycleMBeanBase.java Mon May 3 21:40:52 2010 @@ -0,0 +1,243 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.catalina.util; + +import javax.management.InstanceNotFoundException; +import javax.management.MBeanRegistration; +import javax.management.MBeanRegistrationException; +import javax.management.MBeanServer; +import javax.management.MalformedObjectNameException; +import javax.management.ObjectName; + +import org.apache.catalina.Globals; +import org.apache.catalina.LifecycleException; +import org.apache.juli.logging.Log; +import org.apache.juli.logging.LogFactory; +import org.apache.tomcat.util.modeler.Registry; +import org.apache.tomcat.util.res.StringManager; + +public abstract class LifecycleMBeanBase extends LifecycleBase + implements MBeanRegistration { + + private static Log log = LogFactory.getLog(LifecycleMBeanBase.class); + + private static StringManager sm = + StringManager.getManager("org.apache.catalina.util"); + + + /* Cache components of the MBean registration. */ + private String domain = null; + private ObjectName oname = null; + protected MBeanServer mserver = null; + + /** + * Sub-classes wishing to perform additional initialization should override + * this method, ensuring that super.initInternal() is the first call in the + * overriding method. + */ + @Override + protected void initInternal() throws LifecycleException { + + // If oname is not null then registration has already happened via + // preRegister(). + if (oname == null) { + mserver = Registry.getRegistry(null, null).getMBeanServer(); + + oname = register(this, getObjectNameKeyProperties()); + } + } + + + /** + * Sub-classes wishing to perform additional clean-up should override this + * method, ensuring that super.destroyInternal() is the last call in the + * overriding method. + */ + @Override + protected void destroyInternal() throws LifecycleException { + unregister(oname); + } + + + /** + * Specify the domain under which this component should be registered. Used + * with components that cannot (easily) navigate the component hierarchy to + * determine the correct domain to use. + */ + public final void setDomain(String domain) { + this.domain = domain; + } + + + /** + * Obtain the domain under which this component will be / has been + * registered. + */ + public String getDomain() { + if (domain == null) { + domain = getDomainInternal(); + } + + if (domain == null) { + domain = Globals.DEFAULT_MBEAN_DOMAIN; + } + + return domain; + } + + + /** + * Method implemented by sub-classes to identify the domain in which MBeans + * should be registered. + * + * @return The name of the domain to use to register MBeans. + */ + protected abstract String getDomainInternal(); + + + /** + * Obtain the name under which this component has been registered with JMX. + */ + public final ObjectName getObjectName() { + return oname; + } + + + /** + * Allow sub-classes to specify the key properties component of the + * {...@link ObjectName} that will be used to register this component. + * + * @return The string representation of the key properties component of the + * desired {...@link ObjectName} + */ + protected abstract String getObjectNameKeyProperties(); + + + /** + * Utility method to enable sub-classes to easily register additional + * components that don't implement {...@link LifecycleMBeanRegistration} with + * an MBean server.<br/> + * Note: This method can only be used once {...@link #initInternal()} has been + * called. + * + * @param obj The object the register + * @param objectNameKeyProperties The key properties component of the + * object name to use to register the + * object + * + * @return The name used to register the object + */ + protected final ObjectName register(Object obj, + String objectNameKeyProperties) { + + // Construct an object name with the right domain + StringBuilder name = new StringBuilder(getDomain()); + name.append(':'); + name.append(objectNameKeyProperties); + + ObjectName on = null; + + try { + on = new ObjectName(name.toString()); + + Registry.getRegistry(null, null).registerComponent(obj, on, null); + } catch (MalformedObjectNameException e) { + log.warn(sm.getString("lifecycleMBeanBase.registerFail", obj, name), + e); + } catch (Exception e) { + log.warn(sm.getString("lifecycleMBeanBase.registerFail", obj, name), + e); + } + + return on; + } + + + /** + * Utility method to enable sub-classes to easily unregister additional + * components that don't implement {...@link LifecycleMBeanRegistration} with + * an MBean server. + * @param on The name of the component to unregister + */ + protected final void unregister(ObjectName on) { + + // If null ObjectName, just return without complaint + if (on == null) { + return; + } + + // If the MBeanServer is null, log a warning & return + if (mserver == null) { + log.warn(sm.getString("lifecycleMBeanBase.unregisterNoServer", on)); + return; + } + + try { + mserver.unregisterMBean(on); + } catch (MBeanRegistrationException e) { + log.warn(sm.getString("lifecycleMBeanBase.unregisterFail", on), e); + } catch (InstanceNotFoundException e) { + log.warn(sm.getString("lifecycleMBeanBase.unregisterFail", on), e); + } + + } + + + /** + * Not used - NOOP. + */ + @Override + public final void postDeregister() { + // NOOP + } + + + /** + * Not used - NOOP. + */ + @Override + public final void postRegister(Boolean registrationDone) { + // NOOP + } + + + /** + * Not used - NOOP. + */ + @Override + public final void preDeregister() throws Exception { + // NOOP + } + + + /** + * Allows the object to be registered with an alternative + * {...@link MBeanServer} and/or {...@link ObjectName}. + */ + @Override + public final ObjectName preRegister(MBeanServer server, ObjectName name) + throws Exception { + + this.mserver = server; + this.oname = name; + this.domain = name.getDomain(); + + return oname; + } + +} Propchange: tomcat/trunk/java/org/apache/catalina/util/LifecycleMBeanBase.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: tomcat/trunk/java/org/apache/catalina/util/LocalStrings.properties URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/util/LocalStrings.properties?rev=940634&r1=940633&r2=940634&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/util/LocalStrings.properties (original) +++ tomcat/trunk/java/org/apache/catalina/util/LocalStrings.properties Mon May 3 21:40:52 2010 @@ -27,6 +27,9 @@ lifecycleBase.alreadyStarted=The start() lifecycleBase.alreadyStopped=The stop() method was called on component [{0}] after stop() had already been called. The second call will be ignored. lifecycleBase.alreadyDestroyed=The destroy() method was called on component [{0}] after destroy() had already been called. The second call will be ignored. lifecycleBase.invalidTransition=An invalid Lifecycle transition was attempted ([{0}]) for component [{1}] in state [{2}] +lifecycleMBeanBase.registerFail=Failed to register object [{0}] with name [{0}] during component initialisation +lifecycleMBeanBase.unregisterFail=Failed to unregister MBean with name [{0}] during component destruction +lifecycleMBeanBase.unregisterNoServer=No MBean server was available to unregister the MBean [{0}] requestUtil.convertHexDigit.notHex=[{0}] is not a hexadecimal digit requestUtil.parseParameters.uee=Unable to parse the parameters since the encoding [{0}] is not supported. requestUtil.urlDecode.missingDigit=The % character must be followed by two hexademical digits Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11Protocol.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11Protocol.java?rev=940634&r1=940633&r2=940634&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/Http11Protocol.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/Http11Protocol.java Mon May 3 21:40:52 2010 @@ -160,6 +160,11 @@ public class Http11Protocol extends Abst } + @Override + public void destroy() throws Exception { + cHandler.recycledProcessors.clear(); + super.destroy(); + } // ------------------------------------------------------------- Properties Copied: tomcat/trunk/test/org/apache/catalina/mbeans/TestRegistration.java (from r940487, tomcat/trunk/test/org/apache/catalina/mbeans/RegistrationTest.java) URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/catalina/mbeans/TestRegistration.java?p2=tomcat/trunk/test/org/apache/catalina/mbeans/TestRegistration.java&p1=tomcat/trunk/test/org/apache/catalina/mbeans/RegistrationTest.java&r1=940487&r2=940634&rev=940634&view=diff ============================================================================== --- tomcat/trunk/test/org/apache/catalina/mbeans/RegistrationTest.java (original) +++ tomcat/trunk/test/org/apache/catalina/mbeans/TestRegistration.java Mon May 3 21:40:52 2010 @@ -32,7 +32,7 @@ import org.apache.tomcat.util.modeler.Re * don't necessarily apply to one specific Tomcat class. * */ -public class RegistrationTest extends TomcatBaseTest { +public class TestRegistration extends TomcatBaseTest { /** * Test verifying that Tomcat correctly de-registers the MBeans it has Modified: tomcat/trunk/test/org/apache/catalina/startup/TomcatBaseTest.java URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/catalina/startup/TomcatBaseTest.java?rev=940634&r1=940633&r2=940634&view=diff ============================================================================== --- tomcat/trunk/test/org/apache/catalina/startup/TomcatBaseTest.java (original) +++ tomcat/trunk/test/org/apache/catalina/startup/TomcatBaseTest.java Mon May 3 21:40:52 2010 @@ -33,6 +33,8 @@ import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.apache.catalina.Lifecycle; +import org.apache.catalina.LifecycleState; import org.apache.tomcat.util.buf.ByteChunk; import junit.framework.TestCase; @@ -103,7 +105,12 @@ public abstract class TomcatBaseTest ext @Override public void tearDown() throws Exception { - tomcat.stop(); + // Some tests may call tomcat.destroy(). In which case, don't + // call stop() + if (tomcat.server != null && + tomcat.server.getState() != LifecycleState.DESTROYED) { + tomcat.stop(); + } ExpandWar.delete(tempDir); } --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org