KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > activemq > broker > jmx > ManagementContext


1 /**
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one or more
4  * contributor license agreements. See the NOTICE file distributed with
5  * this work for additional information regarding copyright ownership.
6  * The ASF licenses this file to You under the Apache License, Version 2.0
7  * (the "License"); you may not use this file except in compliance with
8  * the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */

18 package org.apache.activemq.broker.jmx;
19
20 import java.io.IOException JavaDoc;
21 import java.lang.reflect.InvocationTargetException JavaDoc;
22 import java.lang.reflect.Method JavaDoc;
23 import java.net.MalformedURLException JavaDoc;
24 import java.rmi.registry.LocateRegistry JavaDoc;
25 import java.util.List JavaDoc;
26 import javax.management.Attribute JavaDoc;
27 import javax.management.JMException JavaDoc;
28 import javax.management.MBeanServer JavaDoc;
29 import javax.management.MBeanServerFactory JavaDoc;
30 import javax.management.MalformedObjectNameException JavaDoc;
31 import javax.management.ObjectName JavaDoc;
32 import javax.management.remote.JMXConnectorServer JavaDoc;
33 import javax.management.remote.JMXConnectorServerFactory JavaDoc;
34 import javax.management.remote.JMXServiceURL JavaDoc;
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 JavaDoc;
40 /**
41  * A Flow provides different dispatch policies within the NMR
42  *
43  * @org.apache.xbean.XBean
44  *
45  * @version $Revision$
46  */

47 public class ManagementContext implements Service{
48     /**
49      * Default activemq domain
50      */

51     public static final String JavaDoc DEFAULT_DOMAIN="org.apache.activemq";
52     private final static Log log=LogFactory.getLog(ManagementContext.class);
53     private MBeanServer JavaDoc beanServer;
54     private String JavaDoc 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 JavaDoc connectorPath="/jmxrmi";
63     private AtomicBoolean JavaDoc started=new AtomicBoolean JavaDoc(false);
64     private JMXConnectorServer JavaDoc connectorServer;
65     private ObjectName JavaDoc namingServiceObjectName;
66
67     public ManagementContext(){
68         this(null);
69     }
70
71     public ManagementContext(MBeanServer JavaDoc server){
72         this.beanServer=server;
73     }
74
75     public void start() throws IOException JavaDoc {
76         // lets force the MBeanServer to be created if needed
77
if (started.compareAndSet(false, true)) {
78             getMBeanServer();
79             if (connectorServer != null) {
80                 try {
81                     getMBeanServer().invoke(namingServiceObjectName, "start", null, null);
82                 }
83                 catch (Throwable JavaDoc ignore) {
84                 }
85                 Thread JavaDoc t = new Thread JavaDoc("JMX connector") {
86                     public void run() {
87                         try {
88                             JMXConnectorServer JavaDoc 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 JavaDoc 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 JavaDoc {
106         if (started.compareAndSet(true, false)) {
107             JMXConnectorServer JavaDoc server = connectorServer;
108             connectorServer = null;
109             if (server != null) {
110                 try {
111                     server.stop();
112                 }
113                 catch (IOException JavaDoc 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 JavaDoc ignore) {
120                 }
121             }
122             if (locallyCreateMBeanServer && beanServer != null) {
123                 // check to see if the factory knows about this server
124
List JavaDoc list = MBeanServerFactory.findMBeanServer(null);
125                 if (list != null && !list.isEmpty() && list.contains(beanServer)) {
126                     MBeanServerFactory.releaseMBeanServer(beanServer);
127                 }
128             }
129         }
130     }
131
132     /**
133      * @return Returns the jmxDomainName.
134      */

135     public String JavaDoc getJmxDomainName(){
136         return jmxDomainName;
137     }
138
139     /**
140      * @param jmxDomainName
141      * The jmxDomainName to set.
142      */

143     public void setJmxDomainName(String JavaDoc jmxDomainName){
144         this.jmxDomainName=jmxDomainName;
145     }
146
147     /**
148      * Get the MBeanServer
149      *
150      * @return the MBeanServer
151      */

152     public MBeanServer JavaDoc getMBeanServer(){
153         if(this.beanServer==null){
154             this.beanServer=findMBeanServer();
155         }
156         return beanServer;
157     }
158
159     /**
160      * Set the MBeanServer
161      *
162      * @param beanServer
163      */

164     public void setMBeanServer(MBeanServer JavaDoc beanServer){
165         this.beanServer=beanServer;
166     }
167
168     /**
169      * @return Returns the useMBeanServer.
170      */

171     public boolean isUseMBeanServer(){
172         return useMBeanServer;
173     }
174
175     /**
176      * @param useMBeanServer
177      * The useMBeanServer to set.
178      */

179     public void setUseMBeanServer(boolean useMBeanServer){
180         this.useMBeanServer=useMBeanServer;
181     }
182
183     /**
184      * @return Returns the createMBeanServer flag.
185      */

186     public boolean isCreateMBeanServer(){
187         return createMBeanServer;
188     }
189
190     /**
191      * @param enableJMX
192      * Set createMBeanServer.
193      */

194     public void setCreateMBeanServer(boolean enableJMX){
195         this.createMBeanServer=enableJMX;
196     }
197
198     public boolean isFindTigerMbeanServer() {
199         return findTigerMbeanServer;
200     }
201
202     /**
203      * Enables/disables the searching for the Java 5 platform MBeanServer
204      */

205     public void setFindTigerMbeanServer(boolean findTigerMbeanServer) {
206         this.findTigerMbeanServer = findTigerMbeanServer;
207     }
208
209     /**
210      * Formulate and return the MBean ObjectName of a custom control MBean
211      *
212      * @param type
213      * @param name
214      * @return the JMX ObjectName of the MBean, or <code>null</code> if <code>customName</code> is invalid.
215      */

216     public ObjectName JavaDoc createCustomComponentMBeanName(String JavaDoc type,String JavaDoc name){
217         ObjectName JavaDoc result=null;
218         String JavaDoc tmp=jmxDomainName+":"+"type="+sanitizeString(type)+",name="+sanitizeString(name);
219         try{
220             result=new ObjectName JavaDoc(tmp);
221         }catch(MalformedObjectNameException JavaDoc e){
222             log.error("Couldn't create ObjectName from: "+type+" , "+name);
223         }
224         return result;
225     }
226
227     /**
228      * The ':' and '/' characters are reserved in ObjectNames
229      *
230      * @param in
231      * @return sanitized String
232      */

233     private static String JavaDoc sanitizeString(String JavaDoc in){
234         String JavaDoc 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     /**
244      * Retrive an System ObjectName
245      *
246      * @param domainName
247      * @param containerName
248      * @param theClass
249      * @return the ObjectName
250      * @throws MalformedObjectNameException
251      */

252     public static ObjectName JavaDoc getSystemObjectName(String JavaDoc domainName,String JavaDoc containerName,Class JavaDoc theClass)
253                     throws MalformedObjectNameException JavaDoc,NullPointerException JavaDoc{
254         String JavaDoc tmp=domainName+":"+"type="+theClass.getName()+",name="+getRelativeName(containerName,theClass);
255         return new ObjectName JavaDoc(tmp);
256     }
257
258     private static String JavaDoc getRelativeName(String JavaDoc containerName,Class JavaDoc theClass){
259         String JavaDoc 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     /**
268      * Unregister an MBean
269      *
270      * @param name
271      * @throws JMException
272      */

273     public void unregisterMBean(ObjectName JavaDoc name) throws JMException JavaDoc{
274         if(beanServer!=null&&beanServer.isRegistered(name)){
275             beanServer.unregisterMBean(name);
276         }
277     }
278
279     protected synchronized MBeanServer JavaDoc findMBeanServer(){
280         MBeanServer JavaDoc result=null;
281         // create the mbean server
282
try{
283             if(useMBeanServer){
284                 if (findTigerMbeanServer) {
285                     result = findTigerMBeanServer();
286                 }
287                 if (result == null) {
288                     // lets piggy back on another MBeanServer -
289
// we could be in an appserver!
290
List JavaDoc list=MBeanServerFactory.findMBeanServer(null);
291                     if(list!=null&&list.size()>0){
292                         result=(MBeanServer JavaDoc) 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 JavaDoc e) {
305             log.error("Could not load MBeanServer", e);
306         }
307         catch (Throwable JavaDoc e) {
308             // probably don't have access to system properties
309
log.error("Failed to initialize MBeanServer", e);
310         }
311         return result;
312     }
313
314     public static MBeanServer JavaDoc findTigerMBeanServer() {
315         String JavaDoc name = "java.lang.management.ManagementFactory";
316         Class JavaDoc type = loadClass(name, ManagementContext.class.getClassLoader());
317         if (type != null) {
318             try {
319                 Method JavaDoc method = type.getMethod("getPlatformMBeanServer", new Class JavaDoc[0]);
320                 if (method != null) {
321                     Object JavaDoc answer = method.invoke(null, new Object JavaDoc[0]);
322                     if (answer instanceof MBeanServer JavaDoc) {
323                         return (MBeanServer JavaDoc) 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 JavaDoc 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 JavaDoc loadClass(String JavaDoc name, ClassLoader JavaDoc loader) {
344         try {
345             return loader.loadClass(name);
346         }
347         catch (ClassNotFoundException JavaDoc e) {
348             try {
349                 return Thread.currentThread().getContextClassLoader().loadClass(name);
350             }
351             catch (ClassNotFoundException JavaDoc e1) {
352                 return null;
353             }
354         }
355     }
356
357     /**
358      * @return
359      * @throws NullPointerException
360      * @throws MalformedObjectNameException
361      * @throws IOException
362      */

363     protected MBeanServer JavaDoc createMBeanServer() throws MalformedObjectNameException JavaDoc,IOException JavaDoc{
364         MBeanServer JavaDoc mbeanServer=MBeanServerFactory.createMBeanServer(jmxDomainName);
365         locallyCreateMBeanServer=true;
366         if(createConnector){
367             createConnector(mbeanServer);
368         }
369         return mbeanServer;
370     }
371
372     /**
373      * @param mbeanServer
374      * @throws MalformedObjectNameException
375      * @throws MalformedURLException
376      * @throws IOException
377      */

378     private void createConnector(MBeanServer JavaDoc mbeanServer) throws MalformedObjectNameException JavaDoc,MalformedURLException JavaDoc,
379                     IOException JavaDoc{
380         // Create the NamingService, needed by JSR 160
381
try{
382             LocateRegistry.createRegistry(connectorPort);
383             namingServiceObjectName=ObjectName.getInstance("naming:type=rmiregistry");
384             // Do not use the createMBean as the mx4j jar may not be in the
385
// same class loader than the server
386
Class JavaDoc cl=Class.forName("mx4j.tools.naming.NamingService");
387             mbeanServer.registerMBean(cl.newInstance(),namingServiceObjectName);
388             // mbeanServer.createMBean("mx4j.tools.naming.NamingService", namingServiceObjectName, null);
389
// set the naming port
390
Attribute JavaDoc attr=new Attribute JavaDoc("Port",new Integer JavaDoc(connectorPort));
391             mbeanServer.setAttribute(namingServiceObjectName,attr);
392         }catch(Throwable JavaDoc e){
393             log.debug("Failed to create local registry",e);
394         }
395         // Create the JMXConnectorServer
396
String JavaDoc rmiServer = "";
397     if (rmiServerPort != 0) {
398         // This is handy to use if you have a firewall and need to
399
// force JMX to use fixed ports.
400
rmiServer = "localhost:" + rmiServerPort;
401     }
402     String JavaDoc serviceURL = "service:jmx:rmi://"+rmiServer+"/jndi/rmi://localhost:"+connectorPort+connectorPath;
403         JMXServiceURL JavaDoc url=new JMXServiceURL JavaDoc(serviceURL);
404         connectorServer=JMXConnectorServerFactory.newJMXConnectorServer(url,null,mbeanServer);
405     }
406
407     public String JavaDoc getConnectorPath(){
408         return connectorPath;
409     }
410
411     public void setConnectorPath(String JavaDoc 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