From c5f96e1db54a186cb6e8e9430d22704af418248e Mon Sep 17 00:00:00 2001 From: Robert Davies Date: Fri, 10 Mar 2006 09:11:56 +0000 Subject: [PATCH] added some state to avoid npe when starting the connectorServer after stop has been called git-svn-id: https://svn.apache.org/repos/asf/incubator/activemq/trunk@384738 13f79535-47bb-0310-9956-ffa450edef68 --- .../broker/jmx/ManagementContext.java | 319 +++++++++--------- 1 file changed, 151 insertions(+), 168 deletions(-) diff --git a/activemq-core/src/main/java/org/apache/activemq/broker/jmx/ManagementContext.java b/activemq-core/src/main/java/org/apache/activemq/broker/jmx/ManagementContext.java index 3e952ac297..9f9017939e 100644 --- a/activemq-core/src/main/java/org/apache/activemq/broker/jmx/ManagementContext.java +++ b/activemq-core/src/main/java/org/apache/activemq/broker/jmx/ManagementContext.java @@ -1,18 +1,15 @@ /** - * + * * Copyright 2005-2006 The Apache Software Foundation - * - * Licensed 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 - * + * + * Licensed 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. + * + * 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.activemq.broker.jmx; @@ -20,7 +17,6 @@ import java.io.IOException; import java.net.MalformedURLException; import java.rmi.registry.LocateRegistry; import java.util.List; - import javax.management.Attribute; import javax.management.JMException; import javax.management.MBeanServer; @@ -30,11 +26,10 @@ import javax.management.ObjectName; import javax.management.remote.JMXConnectorServer; import javax.management.remote.JMXConnectorServerFactory; import javax.management.remote.JMXServiceURL; - import org.apache.activemq.Service; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; - +import edu.emory.mathcs.backport.java.util.concurrent.atomic.AtomicBoolean; /** * A Flow provides different dispatch policies within the NMR * @@ -42,79 +37,77 @@ import org.apache.commons.logging.LogFactory; * * @version $Revision$ */ -public class ManagementContext implements Service { +public class ManagementContext implements Service{ /** * Default activemq domain */ - public static final String DEFAULT_DOMAIN = "org.apache.activemq"; - - private final static Log log = LogFactory.getLog(ManagementContext.class); - + public static final String DEFAULT_DOMAIN="org.apache.activemq"; + private final static Log log=LogFactory.getLog(ManagementContext.class); private MBeanServer beanServer; - private String jmxDomainName = DEFAULT_DOMAIN; - private boolean useMBeanServer = true; - private boolean createMBeanServer = true; - private boolean locallyCreateMBeanServer = false; - - private boolean createConnector = true; - private int connectorPort = 1099; - private String connectorPath = "/jmxrmi"; - + private String jmxDomainName=DEFAULT_DOMAIN; + private boolean useMBeanServer=true; + private boolean createMBeanServer=true; + private boolean locallyCreateMBeanServer=false; + private boolean createConnector=true; + private int connectorPort=1099; + private String connectorPath="/jmxrmi"; + private AtomicBoolean started=new AtomicBoolean(false); private JMXConnectorServer connectorServer; - private ObjectName namingServiceObjectName; - public ManagementContext() { + public ManagementContext(){ this(null); } - public ManagementContext(MBeanServer server) { - this.beanServer = server; + public ManagementContext(MBeanServer server){ + this.beanServer=server; } - public void start() throws IOException { + public void start() throws IOException{ // lets force the MBeanServer to be created if needed - getMBeanServer(); - if( connectorServer!=null ) { - try { - getMBeanServer().invoke(namingServiceObjectName, "start", null, null); - } catch (Throwable ignore) { - } - Thread t = new Thread("JMX connector") { - public void run() { - try { - connectorServer.start(); - log.info("JMX consoles can connect to " + connectorServer.getAddress()); - } catch (IOException e) { - log.warn("Failed to start jmx connector: "+e.getMessage()); + if(started.compareAndSet(false,true)){ + getMBeanServer(); + if(connectorServer!=null){ + try{ + getMBeanServer().invoke(namingServiceObjectName,"start",null,null); + }catch(Throwable ignore){} + Thread t=new Thread("JMX connector"){ + public void run(){ + try{ + if(started.get()&&connectorServer!=null){ + connectorServer.start(); + log.info("JMX consoles can connect to "+connectorServer.getAddress()); + } + }catch(IOException e){ + log.warn("Failed to start jmx connector: "+e.getMessage()); + } } - } - }; - t.setDaemon(true); - t.start(); + }; + t.setDaemon(true); + t.start(); + } } } - public void stop() throws IOException { - - if( connectorServer!=null ) { - try { - connectorServer.stop(); - } catch (IOException e) { - log.warn("Failed to stop jmx connector: "+e.getMessage()); + public void stop() throws IOException{ + if(started.compareAndSet(true,false)){ + if(connectorServer!=null){ + try{ + connectorServer.stop(); + }catch(IOException e){ + log.warn("Failed to stop jmx connector: "+e.getMessage()); + } + connectorServer=null; + try{ + getMBeanServer().invoke(namingServiceObjectName,"stop",null,null); + }catch(Throwable ignore){} } - connectorServer=null; - try { - getMBeanServer().invoke(namingServiceObjectName, "stop", null, null); - } catch (Throwable ignore) { - } - } - - if (locallyCreateMBeanServer && beanServer != null) { - // check to see if the factory knows about this server - List list = MBeanServerFactory.findMBeanServer(null); - if (list != null && !list.isEmpty() && list.contains(beanServer)) { - MBeanServerFactory.releaseMBeanServer(beanServer); + if(locallyCreateMBeanServer&&beanServer!=null){ + // check to see if the factory knows about this server + List list=MBeanServerFactory.findMBeanServer(null); + if(list!=null&&!list.isEmpty()&&list.contains(beanServer)){ + MBeanServerFactory.releaseMBeanServer(beanServer); + } } } } @@ -122,7 +115,7 @@ public class ManagementContext implements Service { /** * @return Returns the jmxDomainName. */ - public String getJmxDomainName() { + public String getJmxDomainName(){ return jmxDomainName; } @@ -130,8 +123,8 @@ public class ManagementContext implements Service { * @param jmxDomainName * The jmxDomainName to set. */ - public void setJmxDomainName(String jmxDomainName) { - this.jmxDomainName = jmxDomainName; + public void setJmxDomainName(String jmxDomainName){ + this.jmxDomainName=jmxDomainName; } /** @@ -139,25 +132,26 @@ public class ManagementContext implements Service { * * @return the MBeanServer */ - public MBeanServer getMBeanServer() { - if (this.beanServer == null) { - this.beanServer = findMBeanServer(); + public MBeanServer getMBeanServer(){ + if(this.beanServer==null){ + this.beanServer=findMBeanServer(); } return beanServer; } - + /** * Set the MBeanServer + * * @param beanServer */ public void setMBeanServer(MBeanServer beanServer){ - this.beanServer = beanServer; + this.beanServer=beanServer; } /** * @return Returns the useMBeanServer. */ - public boolean isUseMBeanServer() { + public boolean isUseMBeanServer(){ return useMBeanServer; } @@ -165,14 +159,14 @@ public class ManagementContext implements Service { * @param useMBeanServer * The useMBeanServer to set. */ - public void setUseMBeanServer(boolean useMBeanServer) { - this.useMBeanServer = useMBeanServer; + public void setUseMBeanServer(boolean useMBeanServer){ + this.useMBeanServer=useMBeanServer; } /** * @return Returns the createMBeanServer flag. */ - public boolean isCreateMBeanServer() { + public boolean isCreateMBeanServer(){ return createMBeanServer; } @@ -180,8 +174,8 @@ public class ManagementContext implements Service { * @param enableJMX * Set createMBeanServer. */ - public void setCreateMBeanServer(boolean enableJMX) { - this.createMBeanServer = enableJMX; + public void setCreateMBeanServer(boolean enableJMX){ + this.createMBeanServer=enableJMX; } /** @@ -189,17 +183,15 @@ public class ManagementContext implements Service { * * @param type * @param name - * @return the JMX ObjectName of the MBean, or null if - * customName is invalid. + * @return the JMX ObjectName of the MBean, or null if customName is invalid. */ - public ObjectName createCustomComponentMBeanName(String type, String name) { - ObjectName result = null; - String tmp = jmxDomainName + ":" + "type=" + sanitizeString(type) + ",name=" + sanitizeString(name); - try { - result = new ObjectName(tmp); - } - catch (MalformedObjectNameException e) { - log.error("Couldn't create ObjectName from: " + type + " , " + name); + public ObjectName createCustomComponentMBeanName(String type,String name){ + ObjectName result=null; + String tmp=jmxDomainName+":"+"type="+sanitizeString(type)+",name="+sanitizeString(name); + try{ + result=new ObjectName(tmp); + }catch(MalformedObjectNameException e){ + log.error("Couldn't create ObjectName from: "+type+" , "+name); } return result; } @@ -210,12 +202,12 @@ public class ManagementContext implements Service { * @param in * @return sanitized String */ - private static String sanitizeString(String in) { - String result = null; - if (in != null) { - result = in.replace(':', '_'); - result = result.replace('/', '_'); - result = result.replace('\\', '_'); + private static String sanitizeString(String in){ + String result=null; + if(in!=null){ + result=in.replace(':','_'); + result=result.replace('/','_'); + result=result.replace('\\','_'); } return result; } @@ -229,20 +221,19 @@ public class ManagementContext implements Service { * @return the ObjectName * @throws MalformedObjectNameException */ - public static ObjectName getSystemObjectName(String domainName, String containerName, Class theClass) - throws MalformedObjectNameException, NullPointerException { - String tmp = domainName + ":" + "type=" + theClass.getName() + ",name=" - + getRelativeName(containerName, theClass); + public static ObjectName getSystemObjectName(String domainName,String containerName,Class theClass) + throws MalformedObjectNameException,NullPointerException{ + String tmp=domainName+":"+"type="+theClass.getName()+",name="+getRelativeName(containerName,theClass); return new ObjectName(tmp); } - private static String getRelativeName(String containerName, Class theClass) { - String name = theClass.getName(); - int index = name.lastIndexOf("."); - if (index >= 0 && (index + 1) < name.length()) { - name = name.substring(index + 1); + private static String getRelativeName(String containerName,Class theClass){ + String name=theClass.getName(); + int index=name.lastIndexOf("."); + if(index>=0&&(index+1) 0) { - result = (MBeanServer) list.get(0); + List list=MBeanServerFactory.findMBeanServer(null); + if(list!=null&&list.size()>0){ + result=(MBeanServer) list.get(0); } } - - if (result == null && createMBeanServer) { - result = createMBeanServer(); + if(result==null&&createMBeanServer){ + result=createMBeanServer(); } - } - catch (NoClassDefFoundError e) { - log.error("Couldnot load MBeanServer", e); - } - catch (Throwable e) { + }catch(NoClassDefFoundError e){ + log.error("Couldnot load MBeanServer",e); + }catch(Throwable e){ // probably don't have access to system properties - log.error("Failed to initialize MBeanServer", e); + log.error("Failed to initialize MBeanServer",e); } return result; } /** * @return - * @throws NullPointerException - * @throws MalformedObjectNameException - * @throws IOException + * @throws NullPointerException + * @throws MalformedObjectNameException + * @throws IOException */ - protected MBeanServer createMBeanServer() throws MalformedObjectNameException, IOException { - MBeanServer mbeanServer = MBeanServerFactory.createMBeanServer(jmxDomainName); - locallyCreateMBeanServer = true; - - if( createConnector ) { + protected MBeanServer createMBeanServer() throws MalformedObjectNameException,IOException{ + MBeanServer mbeanServer=MBeanServerFactory.createMBeanServer(jmxDomainName); + locallyCreateMBeanServer=true; + if(createConnector){ createConnector(mbeanServer); } - - return mbeanServer; } @@ -308,53 +293,51 @@ public class ManagementContext implements Service { * @throws MalformedURLException * @throws IOException */ - private void createConnector(MBeanServer mbeanServer) throws MalformedObjectNameException, MalformedURLException, IOException { - + private void createConnector(MBeanServer mbeanServer) throws MalformedObjectNameException,MalformedURLException, + IOException{ // Create the NamingService, needed by JSR 160 - try { + try{ LocateRegistry.createRegistry(connectorPort); - - namingServiceObjectName = ObjectName.getInstance("naming:type=rmiregistry"); - -// Do not use the createMBean as the mx4j jar may not be in the + namingServiceObjectName=ObjectName.getInstance("naming:type=rmiregistry"); + // Do not use the createMBean as the mx4j jar may not be in the // same class loader than the server - Class cl = Class.forName("mx4j.tools.naming.NamingService"); - mbeanServer.registerMBean(cl.newInstance(), namingServiceObjectName); - //mbeanServer.createMBean("mx4j.tools.naming.NamingService", namingServiceObjectName, null); - + Class cl=Class.forName("mx4j.tools.naming.NamingService"); + mbeanServer.registerMBean(cl.newInstance(),namingServiceObjectName); + // mbeanServer.createMBean("mx4j.tools.naming.NamingService", namingServiceObjectName, null); // set the naming port - Attribute attr = new Attribute("Port", new Integer(connectorPort)); - mbeanServer.setAttribute(namingServiceObjectName, attr); - } catch (Throwable e) { - log.debug("Failed to create local registry", e); + Attribute attr=new Attribute("Port",new Integer(connectorPort)); + mbeanServer.setAttribute(namingServiceObjectName,attr); + }catch(Throwable e){ + log.debug("Failed to create local registry",e); } - // Create the JMXConnectorServer - String serviceURL = "service:jmx:rmi:///jndi/rmi://localhost:" + connectorPort + connectorPath; - JMXServiceURL url = new JMXServiceURL(serviceURL); - connectorServer = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbeanServer); - - //log.info("JMX consoles can connect to serviceURL: " + serviceURL); + String serviceURL="service:jmx:rmi:///jndi/rmi://localhost:"+connectorPort+connectorPath; + JMXServiceURL url=new JMXServiceURL(serviceURL); + connectorServer=JMXConnectorServerFactory.newJMXConnectorServer(url,null,mbeanServer); + // log.info("JMX consoles can connect to serviceURL: " + serviceURL); } - public String getConnectorPath() { + public String getConnectorPath(){ return connectorPath; } - public void setConnectorPath(String connectorPath) { - this.connectorPath = connectorPath; + + public void setConnectorPath(String connectorPath){ + this.connectorPath=connectorPath; } - public int getConnectorPort() { + public int getConnectorPort(){ return connectorPort; } - public void setConnectorPort(int connectorPort) { - this.connectorPort = connectorPort; + + public void setConnectorPort(int connectorPort){ + this.connectorPort=connectorPort; } - public boolean isCreateConnector() { + public boolean isCreateConnector(){ return createConnector; } - public void setCreateConnector(boolean createConnector) { - this.createConnector = createConnector; + + public void setCreateConnector(boolean createConnector){ + this.createConnector=createConnector; } } \ No newline at end of file