1 18 package org.apache.activemq.broker.jmx; 19 20 import java.io.IOException ; 21 import java.lang.reflect.InvocationTargetException ; 22 import java.lang.reflect.Method ; 23 import java.net.MalformedURLException ; 24 import java.rmi.registry.LocateRegistry ; 25 import java.util.List ; 26 import javax.management.Attribute ; 27 import javax.management.JMException ; 28 import javax.management.MBeanServer ; 29 import javax.management.MBeanServerFactory ; 30 import javax.management.MalformedObjectNameException ; 31 import javax.management.ObjectName ; 32 import javax.management.remote.JMXConnectorServer ; 33 import javax.management.remote.JMXConnectorServerFactory ; 34 import javax.management.remote.JMXServiceURL ; 35 import org.apache.activemq.Service; 36 import org.apache.activemq.util.ClassLoading; 37 import org.apache.commons.logging.Log; 38 import org.apache.commons.logging.LogFactory; 39 import java.util.concurrent.atomic.AtomicBoolean ; 40 47 public class ManagementContext implements Service{ 48 51 public static final String DEFAULT_DOMAIN="org.apache.activemq"; 52 private final static Log log=LogFactory.getLog(ManagementContext.class); 53 private MBeanServer beanServer; 54 private String jmxDomainName=DEFAULT_DOMAIN; 55 private boolean useMBeanServer=true; 56 private boolean createMBeanServer=true; 57 private boolean locallyCreateMBeanServer=false; 58 private boolean createConnector=true; 59 private boolean findTigerMbeanServer=false; 60 private int connectorPort=1099; 61 private int rmiServerPort; 62 private String connectorPath="/jmxrmi"; 63 private AtomicBoolean started=new AtomicBoolean (false); 64 private JMXConnectorServer connectorServer; 65 private ObjectName namingServiceObjectName; 66 67 public ManagementContext(){ 68 this(null); 69 } 70 71 public ManagementContext(MBeanServer server){ 72 this.beanServer=server; 73 } 74 75 public void start() throws IOException { 76 if (started.compareAndSet(false, true)) { 78 getMBeanServer(); 79 if (connectorServer != null) { 80 try { 81 getMBeanServer().invoke(namingServiceObjectName, "start", null, null); 82 } 83 catch (Throwable ignore) { 84 } 85 Thread t = new Thread ("JMX connector") { 86 public void run() { 87 try { 88 JMXConnectorServer server = connectorServer; 89 if (started.get() && server != null) { 90 server.start(); 91 log.info("JMX consoles can connect to " + server.getAddress()); 92 } 93 } 94 catch (IOException e) { 95 log.warn("Failed to start jmx connector: " + e.getMessage()); 96 } 97 } 98 }; 99 t.setDaemon(true); 100 t.start(); 101 } 102 } 103 } 104 105 public void stop() throws IOException { 106 if (started.compareAndSet(true, false)) { 107 JMXConnectorServer server = connectorServer; 108 connectorServer = null; 109 if (server != null) { 110 try { 111 server.stop(); 112 } 113 catch (IOException e) { 114 log.warn("Failed to stop jmx connector: " + e.getMessage()); 115 } 116 try { 117 getMBeanServer().invoke(namingServiceObjectName, "stop", null, null); 118 } 119 catch (Throwable ignore) { 120 } 121 } 122 if (locallyCreateMBeanServer && beanServer != null) { 123 List list = MBeanServerFactory.findMBeanServer(null); 125 if (list != null && !list.isEmpty() && list.contains(beanServer)) { 126 MBeanServerFactory.releaseMBeanServer(beanServer); 127 } 128 } 129 } 130 } 131 132 135 public String getJmxDomainName(){ 136 return jmxDomainName; 137 } 138 139 143 public void setJmxDomainName(String jmxDomainName){ 144 this.jmxDomainName=jmxDomainName; 145 } 146 147 152 public MBeanServer getMBeanServer(){ 153 if(this.beanServer==null){ 154 this.beanServer=findMBeanServer(); 155 } 156 return beanServer; 157 } 158 159 164 public void setMBeanServer(MBeanServer beanServer){ 165 this.beanServer=beanServer; 166 } 167 168 171 public boolean isUseMBeanServer(){ 172 return useMBeanServer; 173 } 174 175 179 public void setUseMBeanServer(boolean useMBeanServer){ 180 this.useMBeanServer=useMBeanServer; 181 } 182 183 186 public boolean isCreateMBeanServer(){ 187 return createMBeanServer; 188 } 189 190 194 public void setCreateMBeanServer(boolean enableJMX){ 195 this.createMBeanServer=enableJMX; 196 } 197 198 public boolean isFindTigerMbeanServer() { 199 return findTigerMbeanServer; 200 } 201 202 205 public void setFindTigerMbeanServer(boolean findTigerMbeanServer) { 206 this.findTigerMbeanServer = findTigerMbeanServer; 207 } 208 209 216 public ObjectName createCustomComponentMBeanName(String type,String name){ 217 ObjectName result=null; 218 String tmp=jmxDomainName+":"+"type="+sanitizeString(type)+",name="+sanitizeString(name); 219 try{ 220 result=new ObjectName (tmp); 221 }catch(MalformedObjectNameException e){ 222 log.error("Couldn't create ObjectName from: "+type+" , "+name); 223 } 224 return result; 225 } 226 227 233 private static String sanitizeString(String in){ 234 String result=null; 235 if(in!=null){ 236 result=in.replace(':','_'); 237 result=result.replace('/','_'); 238 result=result.replace('\\','_'); 239 } 240 return result; 241 } 242 243 252 public static ObjectName getSystemObjectName(String domainName,String containerName,Class theClass) 253 throws MalformedObjectNameException ,NullPointerException { 254 String tmp=domainName+":"+"type="+theClass.getName()+",name="+getRelativeName(containerName,theClass); 255 return new ObjectName (tmp); 256 } 257 258 private static String getRelativeName(String containerName,Class theClass){ 259 String name=theClass.getName(); 260 int index=name.lastIndexOf("."); 261 if(index>=0&&(index+1)<name.length()){ 262 name=name.substring(index+1); 263 } 264 return containerName+"."+name; 265 } 266 267 273 public void unregisterMBean(ObjectName name) throws JMException { 274 if(beanServer!=null&&beanServer.isRegistered(name)){ 275 beanServer.unregisterMBean(name); 276 } 277 } 278 279 protected synchronized MBeanServer findMBeanServer(){ 280 MBeanServer result=null; 281 try{ 283 if(useMBeanServer){ 284 if (findTigerMbeanServer) { 285 result = findTigerMBeanServer(); 286 } 287 if (result == null) { 288 List list=MBeanServerFactory.findMBeanServer(null); 291 if(list!=null&&list.size()>0){ 292 result=(MBeanServer ) list.get(0); 293 } 294 } 295 } 296 if (result == null && createMBeanServer) { 297 result = createMBeanServer(); 298 } 299 300 if (result != null && createConnector) { 301 createConnector(result); 302 } 303 } 304 catch (NoClassDefFoundError e) { 305 log.error("Could not load MBeanServer", e); 306 } 307 catch (Throwable e) { 308 log.error("Failed to initialize MBeanServer", e); 310 } 311 return result; 312 } 313 314 public static MBeanServer findTigerMBeanServer() { 315 String name = "java.lang.management.ManagementFactory"; 316 Class type = loadClass(name, ManagementContext.class.getClassLoader()); 317 if (type != null) { 318 try { 319 Method method = type.getMethod("getPlatformMBeanServer", new Class [0]); 320 if (method != null) { 321 Object answer = method.invoke(null, new Object [0]); 322 if (answer instanceof MBeanServer ) { 323 return (MBeanServer ) answer; 324 } 325 else { 326 log.warn("Could not cast: " + answer + " into an MBeanServer. There must be some classloader strangeness in town"); 327 } 328 } 329 else { 330 log.warn("Method getPlatformMBeanServer() does not appear visible on type: " + type.getName()); 331 } 332 } 333 catch (Exception e) { 334 log.warn("Failed to call getPlatformMBeanServer() due to: " + e, e); 335 } 336 } 337 else { 338 log.trace("Class not found: " + name + " so probably running on Java 1.4"); 339 } 340 return null; 341 } 342 343 private static Class loadClass(String name, ClassLoader loader) { 344 try { 345 return loader.loadClass(name); 346 } 347 catch (ClassNotFoundException e) { 348 try { 349 return Thread.currentThread().getContextClassLoader().loadClass(name); 350 } 351 catch (ClassNotFoundException e1) { 352 return null; 353 } 354 } 355 } 356 357 363 protected MBeanServer createMBeanServer() throws MalformedObjectNameException ,IOException { 364 MBeanServer mbeanServer=MBeanServerFactory.createMBeanServer(jmxDomainName); 365 locallyCreateMBeanServer=true; 366 if(createConnector){ 367 createConnector(mbeanServer); 368 } 369 return mbeanServer; 370 } 371 372 378 private void createConnector(MBeanServer mbeanServer) throws MalformedObjectNameException ,MalformedURLException , 379 IOException { 380 try{ 382 LocateRegistry.createRegistry(connectorPort); 383 namingServiceObjectName=ObjectName.getInstance("naming:type=rmiregistry"); 384 Class cl=Class.forName("mx4j.tools.naming.NamingService"); 387 mbeanServer.registerMBean(cl.newInstance(),namingServiceObjectName); 388 Attribute attr=new Attribute ("Port",new Integer (connectorPort)); 391 mbeanServer.setAttribute(namingServiceObjectName,attr); 392 }catch(Throwable e){ 393 log.debug("Failed to create local registry",e); 394 } 395 String rmiServer = ""; 397 if (rmiServerPort != 0) { 398 rmiServer = "localhost:" + rmiServerPort; 401 } 402 String serviceURL = "service:jmx:rmi://"+rmiServer+"/jndi/rmi://localhost:"+connectorPort+connectorPath; 403 JMXServiceURL url=new JMXServiceURL (serviceURL); 404 connectorServer=JMXConnectorServerFactory.newJMXConnectorServer(url,null,mbeanServer); 405 } 406 407 public String getConnectorPath(){ 408 return connectorPath; 409 } 410 411 public void setConnectorPath(String connectorPath){ 412 this.connectorPath=connectorPath; 413 } 414 415 public int getConnectorPort(){ 416 return connectorPort; 417 } 418 419 public void setConnectorPort(int connectorPort){ 420 this.connectorPort=connectorPort; 421 } 422 423 public int getRmiServerPort(){ 424 return rmiServerPort; 425 } 426 427 public void setRmiServerPort(int rmiServerPort){ 428 this.rmiServerPort=rmiServerPort; 429 } 430 431 public boolean isCreateConnector(){ 432 return createConnector; 433 } 434 435 public void setCreateConnector(boolean createConnector){ 436 this.createConnector=createConnector; 437 } 438 } 439 | Popular Tags |