From 341351b15a7ae4827e2239da66359b570f1e6eff Mon Sep 17 00:00:00 2001 From: markt Date: Sun, 2 May 2010 17:36:38 +0000 Subject: [PATCH] Add new interface to StandardServer to enable MBean (de)registration on init/destroy git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@940273 13f79535-47bb-0310-9956-ffa450edef68 --- java/org/apache/catalina/Globals.java | 5 ++ .../apache/catalina/core/LocalStrings.properties | 1 + java/org/apache/catalina/core/StandardServer.java | 85 ++++++++++++++++------ .../apache/catalina/mbeans/RegistrationTest.java | 85 ++++++++++++++++++++++ 4 files changed, 154 insertions(+), 22 deletions(-) create mode 100644 test/org/apache/catalina/mbeans/RegistrationTest.java diff --git a/java/org/apache/catalina/Globals.java b/java/org/apache/catalina/Globals.java index d36226cd8..fb25b6132 100644 --- a/java/org/apache/catalina/Globals.java +++ b/java/org/apache/catalina/Globals.java @@ -334,4 +334,9 @@ public final class Globals { public static final String ASYNC_SUPPORTED_ATTR = "org.apache.catalina.ASYNC_SUPPORTED"; + + /** + * Default domain for MBeans if none can be determined + */ + public static final String DEFAULT_MBEAN_DOMAIN = "Catalina"; } diff --git a/java/org/apache/catalina/core/LocalStrings.properties b/java/org/apache/catalina/core/LocalStrings.properties index 3d23c0d91..b8b5dbe41 100644 --- a/java/org/apache/catalina/core/LocalStrings.properties +++ b/java/org/apache/catalina/core/LocalStrings.properties @@ -188,6 +188,7 @@ standardHost.warRequired=URL to web application archive is required standardHost.warURL=Invalid URL for web application archive: {0} standardHost.validationEnabled=XML validation enabled standardHost.validationDisabled=XML validation disabled +standardServer.onameFail=MBean name specified for Server [{0}] is not valid standardServer.shutdownViaPort=A valid shutdown command was received via the shutdown port. Stopping the Server instance. standardService.connector.failed=Failed to start connector [{0}] standardService.initialize.failed=Service initializing at {0} failed diff --git a/java/org/apache/catalina/core/StandardServer.java b/java/org/apache/catalina/core/StandardServer.java index 3922d3450..940da2713 100644 --- a/java/org/apache/catalina/core/StandardServer.java +++ b/java/org/apache/catalina/core/StandardServer.java @@ -29,12 +29,15 @@ import java.net.Socket; import java.security.AccessControlException; import java.util.Random; -import javax.management.MBeanRegistration; 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; @@ -47,6 +50,8 @@ import org.apache.juli.logging.LogFactory; import org.apache.tomcat.util.buf.StringCache; import org.apache.tomcat.util.modeler.Registry; +import com.sun.xml.internal.ws.api.pipe.Engine; + /** @@ -57,7 +62,7 @@ import org.apache.tomcat.util.modeler.Registry; * @version $Id$ */ public final class StandardServer extends LifecycleBase - implements Server, MBeanRegistration { + implements Server, LifecycleMBeanRegistration { private static final Log log = LogFactory.getLog(StandardServer.class); @@ -682,17 +687,10 @@ public final class StandardServer extends LifecycleBase @Override protected void initInternal() throws LifecycleException { - if( oname==null ) { - try { - oname=new ObjectName( "Catalina:type=Server"); - Registry.getRegistry(null, null) - .registerComponent(this, oname, null ); - } catch (Exception e) { - log.error("Error registering ",e); - } - } - // 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 { ObjectName oname2 = new ObjectName(oname.getDomain() + ":type=StringCache"); @@ -708,39 +706,82 @@ public final class StandardServer extends LifecycleBase } } + @Override protected void destroyInternal() { // NOOP } - protected String type; - protected String domain; - protected String suffix; - protected ObjectName oname; + protected volatile String domain; + protected volatile ObjectName oname; protected MBeanServer mserver; + /** + * Obtain the MBean domain for this server. The domain is obtained using + * the following search order: + *
    + *
  1. Name of first {@link Engine}.
  2. + *
  3. Name of first {@link Service}.
  4. + *
  5. Global default defined by {@link Globals#DEFAULT_MBEAN_DOMAIN}
  6. + *
+ */ + 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; + } + } + return 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 String getDomain() { - return domain; - } public ObjectName preRegister(MBeanServer server, ObjectName name) throws Exception { - oname=name; - mserver=server; - domain=name.getDomain(); + oname = name; + mserver = server; + domain = name.getDomain(); return name; } public void postRegister(Boolean registrationDone) { + // NOOP } public void preDeregister() throws Exception { + // NOOP } public void postDeregister() { + // NOOP } } diff --git a/test/org/apache/catalina/mbeans/RegistrationTest.java b/test/org/apache/catalina/mbeans/RegistrationTest.java new file mode 100644 index 000000000..5c19e6acb --- /dev/null +++ b/test/org/apache/catalina/mbeans/RegistrationTest.java @@ -0,0 +1,85 @@ +/* + * 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.mbeans; + +import java.io.File; +import java.util.Set; + +import javax.management.MBeanServer; +import javax.management.ObjectName; + +import org.apache.catalina.core.StandardHost; +import org.apache.catalina.startup.Tomcat; +import org.apache.catalina.startup.TomcatBaseTest; +import org.apache.tomcat.util.modeler.Registry; + +/** + * General tests around the process of registration and de-registration that + * don't necessarily apply to one specific Tomcat class. + * + */ +public class RegistrationTest extends TomcatBaseTest { + + /** + * Test verifying that Tomcat correctly de-registers the MBeans it has + * registered. + * @author Marc Guillemot + */ + public void testMBeanDeregistration() throws Exception { + final MBeanServer mbeanServer = Registry.getRegistry(null, null).getMBeanServer(); + Set onames = mbeanServer.queryNames(new ObjectName("Catalina:*"), null); + assertEquals("Remaining: " + onames, 0, onames.size()); + + final Tomcat tomcat = getTomcatInstance(); + // need to register a ServerLifecycleListener otherwise only a few MBeans are registered + tomcat.getServer().addLifecycleListener(new ServerLifecycleListener()); + final File contextDir = new File("output/webappFoo"); + contextDir.mkdir(); + tomcat.addContext("/foo", contextDir.getAbsolutePath()); + tomcat.start(); + + // Verify there are no Catalina MBeans + onames = mbeanServer.queryNames(new ObjectName("Catalina:*"), null); + assertEquals("Found: " + onames, 0, onames.size()); + + // Verify there are some Tomcat MBeans + onames = mbeanServer.queryNames(new ObjectName("Tomcat:*"), null); + assertTrue("No Tomcat MBeans", onames.size() > 0); + + tomcat.stop(); + + // Verify there are no Tomcat MBeans + onames = mbeanServer.queryNames(new ObjectName("Catalina:*"), null); + assertEquals("Remaining: " + onames, 0, onames.size()); + + // add a new host + StandardHost host = new StandardHost(); + host.setName("otherhost"); + tomcat.getEngine().addChild(host); + + final File contextDir2 = new File("output/webappFoo2"); + contextDir2.mkdir(); + tomcat.addContext(host, "/foo2", contextDir2.getAbsolutePath()); + + tomcat.start(); + tomcat.stop(); + + onames = mbeanServer.queryNames(new ObjectName("Catalina:*"), null); + assertEquals("Remaining: " + onames, 0, onames.size()); + } + +} -- 2.11.0