KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > jmx > Jmx


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  *
23  * Free Software Foundation, Inc.
24  * 59 Temple Place, Suite 330
25  * Boston, MA 02111-1307 USA
26  *
27  * @author Scott Ferguson
28  */

29
30 package com.caucho.jmx;
31
32 import com.caucho.log.Log;
33 import com.caucho.util.Alarm;
34 import com.caucho.util.CharBuffer;
35 import com.caucho.util.L10N;
36
37 import javax.management.*;
38 import java.lang.reflect.Method JavaDoc;
39 import java.util.ArrayList JavaDoc;
40 import java.util.Iterator JavaDoc;
41 import java.util.LinkedHashMap JavaDoc;
42 import java.util.Map JavaDoc;
43 import java.util.Set JavaDoc;
44 import java.util.TimerTask JavaDoc;
45 import java.util.logging.Level JavaDoc;
46 import java.util.logging.Logger JavaDoc;
47
48 /**
49  * Static convenience methods.
50  */

51 public class Jmx {
52   private static final L10N L = new L10N(Jmx.class);
53   private static final Logger JavaDoc log = Log.open(Jmx.class);
54
55   private static EnvironmentMBeanServer _mbeanServer;
56   private static MBeanServer _globalMBeanServer;
57
58   /**
59    * Sets the server.
60    */

61   static void setMBeanServer(EnvironmentMBeanServer server)
62   {
63     _mbeanServer = server;
64   }
65
66   /**
67    * Returns the context mbean server.
68    */

69   public static MBeanServer getContextMBeanServer()
70   {
71     if (_mbeanServer == null)
72       _mbeanServer = (EnvironmentMBeanServer) EnvironmentMBeanServerBuilder.getGlobal("resin");
73       
74     return _mbeanServer;
75   }
76
77   /**
78    * Returns the global mbean server.
79    */

80   public static MBeanServer getGlobalMBeanServer()
81   {
82     if (_globalMBeanServer == null) {
83       getContextMBeanServer();
84
85       ClassLoader JavaDoc systemLoader = ClassLoader.getSystemClassLoader();
86       _globalMBeanServer = new GlobalMBeanServer(systemLoader);
87     }
88
89     return _globalMBeanServer;
90   }
91
92   /**
93    * Gets the static mbean server.
94    */

95   public static AbstractMBeanServer getMBeanServer()
96   {
97     return _mbeanServer;
98   }
99   
100   /**
101    * Returns a copy of the context properties.
102    */

103   public static LinkedHashMap JavaDoc<String JavaDoc,String JavaDoc> copyContextProperties()
104   {
105     AbstractMBeanServer mbeanServer = getMBeanServer();
106
107     if (mbeanServer != null)
108       return mbeanServer.getContext().copyProperties();
109     else
110       return new LinkedHashMap JavaDoc<String JavaDoc,String JavaDoc>();
111   }
112   
113   /**
114    * Returns a copy of the context properties.
115    */

116   public static LinkedHashMap JavaDoc<String JavaDoc,String JavaDoc>
117     copyContextProperties(ClassLoader JavaDoc loader)
118   {
119     AbstractMBeanServer mbeanServer = getMBeanServer();
120
121     if (mbeanServer != null)
122       return mbeanServer.getContext(loader).copyProperties();
123     else
124       return new LinkedHashMap JavaDoc<String JavaDoc,String JavaDoc>();
125   }
126
127   /**
128    * Sets the context properties.
129    */

130   public static void setContextProperties(Map JavaDoc<String JavaDoc,String JavaDoc> properties)
131   {
132     AbstractMBeanServer mbeanServer = getMBeanServer();
133
134     if (mbeanServer != null)
135       mbeanServer.getContext().setProperties(properties);
136   }
137
138   /**
139    * Sets the context properties.
140    */

141   public static void setContextProperties(Map JavaDoc<String JavaDoc,String JavaDoc> properties,
142                       ClassLoader JavaDoc loader)
143   {
144     AbstractMBeanServer mbeanServer = getMBeanServer();
145
146     if (mbeanServer != null)
147       mbeanServer.getContext(loader).setProperties(properties);
148   }
149   
150   /**
151    * Conditionally registers an MBean with the server.
152    *
153    * @param object the object to be registered as an MBean
154    * @param name the name of the mbean.
155    *
156    * @return the instantiated object.
157    */

158   public static ObjectInstance register(Object JavaDoc object, String JavaDoc name)
159     throws InstanceAlreadyExistsException,
160        MBeanRegistrationException, MalformedObjectNameException,
161        NotCompliantMBeanException
162   {
163     if (name.indexOf(':') < 0) {
164       Map JavaDoc<String JavaDoc,String JavaDoc> props = parseProperties(name);
165
166       if (props.get("type") == null) {
167     String JavaDoc type = object.getClass().getName();
168     int p = type.lastIndexOf('.');
169     if (p > 0)
170       type = type.substring(p + 1);
171
172     props.put("type", type);
173       }
174
175       ObjectName objectName = getObjectName("resin", props);
176
177       return register(object, objectName);
178     }
179     else
180       return register(object, new ObjectName(name));
181       
182   }
183   
184   /**
185    * Conditionally registers an MBean with the server.
186    *
187    * @param object the object to be registered as an MBean
188    * @param name the name of the mbean.
189    *
190    * @return the instantiated object.
191    */

192   public static ObjectInstance register(Object JavaDoc object,
193                     Map JavaDoc<String JavaDoc,String JavaDoc> properties)
194     throws InstanceAlreadyExistsException,
195        MBeanRegistrationException, MalformedObjectNameException,
196        NotCompliantMBeanException
197   {
198     Map JavaDoc<String JavaDoc,String JavaDoc> props = copyContextProperties();
199     props.putAll(properties);
200
201     return register(object, getObjectName("resin", props));
202   }
203   
204   /**
205    * Registers an MBean with the server.
206    *
207    * @param object the object to be registered as an MBean
208    * @param name the name of the mbean.
209    *
210    * @return the instantiated object.
211    */

212   public static ObjectInstance register(Object JavaDoc object, ObjectName name)
213     throws InstanceAlreadyExistsException,
214        MBeanRegistrationException,
215        NotCompliantMBeanException
216   {
217     return getMBeanServer().registerMBean(createMBean(object, name), name);
218   }
219   
220   /**
221    * Registers an MBean with the server.
222    *
223    * @param object the object to be registered as an MBean
224    * @param name the name of the mbean.
225    *
226    * @return the instantiated object.
227    */

228   public static ObjectInstance register(Object JavaDoc object, ObjectName name,
229                     ClassLoader JavaDoc loader)
230     throws InstanceAlreadyExistsException,
231        MBeanRegistrationException,
232        NotCompliantMBeanException
233   {
234     Thread JavaDoc thread = Thread.currentThread();
235     ClassLoader JavaDoc oldLoader = thread.getContextClassLoader();
236
237     try {
238       thread.setContextClassLoader(loader);
239
240       AbstractMBeanServer mbeanServer = getMBeanServer();
241
242       if (mbeanServer != null)
243     return mbeanServer.registerMBean(createMBean(object, name), name);
244       else
245     return null;
246     } finally {
247       thread.setContextClassLoader(oldLoader);
248     }
249   }
250
251   /**
252    * Creates the dynamic mbean.
253    */

254   private static DynamicMBean createMBean(Object JavaDoc obj, ObjectName name)
255     throws NotCompliantMBeanException
256   {
257     if (obj == null)
258       throw new NotCompliantMBeanException(L.l("{0} mbean is null", name));
259     else if (obj instanceof DynamicMBean)
260       return (DynamicMBean) obj;
261
262     Class JavaDoc ifc = getMBeanInterface(obj.getClass());
263
264     if (ifc == null)
265       throw new NotCompliantMBeanException(L.l("{0} mbean has no MBean interface", name));
266
267     return new IntrospectionMBean(obj, ifc);
268   }
269
270   /**
271    * Returns the mbean interface.
272    */

273   private static Class JavaDoc getMBeanInterface(Class JavaDoc cl)
274   {
275     for (; cl != null; cl = cl.getSuperclass()) {
276       Class JavaDoc []interfaces = cl.getInterfaces();
277
278       for (int i = 0; i < interfaces.length; i++) {
279     Class JavaDoc ifc = interfaces[i];
280     
281     if (ifc.getName().endsWith("MBean") ||
282         ifc.getName().endsWith("MXBean"))
283       return ifc;
284       }
285     }
286
287     return null;
288   }
289   
290   /**
291    * Unregisters an MBean with the server.
292    *
293    * @param name the name of the mbean.
294    */

295   public static void unregister(ObjectName name)
296     throws MBeanRegistrationException,
297        InstanceNotFoundException
298   {
299     getMBeanServer().unregisterMBean(name);
300   }
301   
302   /**
303    * Unregisters an MBean with the server.
304    *
305    * @param name the name of the mbean.
306    */

307   public static void unregister(ObjectName name, ClassLoader JavaDoc loader)
308     throws MBeanRegistrationException,
309        InstanceNotFoundException
310   {
311     Thread JavaDoc thread = Thread.currentThread();
312     ClassLoader JavaDoc oldLoader = thread.getContextClassLoader();
313
314     try {
315       thread.setContextClassLoader(loader);
316       
317       getMBeanServer().unregisterMBean(name);
318     } finally {
319       thread.setContextClassLoader(oldLoader);
320     }
321   }
322   
323   /**
324    * Registers an MBean with the server.
325    *
326    * @param object the object to be registered as an MBean
327    * @param name the name of the mbean.
328    * @param api the api for the server
329    *
330    * @return the instantiated object.
331    */

332   public static ObjectInstance register(Object JavaDoc object,
333                     String JavaDoc name,
334                     Class JavaDoc api)
335     throws InstanceAlreadyExistsException,
336        MBeanRegistrationException,
337        MalformedObjectNameException,
338        NotCompliantMBeanException
339   {
340     return register(object, new ObjectName(name), api);
341   }
342   
343   /**
344    * Registers an MBean with the server.
345    *
346    * @param object the object to be registered as an MBean
347    * @param name the name of the mbean.
348    * @param api the api for the server
349    *
350    * @return the instantiated object.
351    */

352   public static ObjectInstance register(Object JavaDoc object,
353                     ObjectName name,
354                     Class JavaDoc api)
355     throws InstanceAlreadyExistsException,
356        MBeanRegistrationException, MalformedObjectNameException,
357        NotCompliantMBeanException
358   {
359     IntrospectionMBean mbean = new IntrospectionMBean(object, api);
360     
361     return getMBeanServer().registerMBean(mbean, name);
362   }
363   
364   /**
365    * Conditionally registers an MBean with the server.
366    *
367    * @param object the object to be registered as an MBean
368    * @param name the name of the mbean.
369    *
370    * @return the instantiated object.
371    */

372   public static void unregister(String JavaDoc name)
373     throws InstanceNotFoundException,
374        MalformedObjectNameException,
375        MBeanRegistrationException
376        
377   {
378     ObjectName objectName = getObjectName(name);
379
380     getMBeanServer().unregisterMBean(objectName);
381     // return register(object, objectName);
382
}
383
384   /**
385    * Returns an ObjectName based on a short name.
386    */

387   public static ObjectName getObjectName(String JavaDoc name)
388     throws MalformedObjectNameException
389   {
390     return getMBeanServer().getContext().getObjectName(name);
391   }
392
393   /**
394    * Parses a name.
395    */

396   public static LinkedHashMap JavaDoc<String JavaDoc,String JavaDoc> parseProperties(String JavaDoc name)
397   {
398     LinkedHashMap JavaDoc<String JavaDoc,String JavaDoc> map = new LinkedHashMap JavaDoc<String JavaDoc,String JavaDoc>();
399     
400     parseProperties(map, name);
401
402     return map;
403   }
404
405   /**
406    * Parses a name.
407    */

408   public static void parseProperties(Map JavaDoc<String JavaDoc,String JavaDoc> properties,
409                      String JavaDoc name)
410   {
411     parseProperties(properties, name, 0);
412   }
413
414   /**
415    * Parses a name.
416    */

417   private static void
418     parseProperties(Map JavaDoc<String JavaDoc,String JavaDoc> properties, String JavaDoc name, int i)
419   {
420     CharBuffer cb = CharBuffer.allocate();
421     
422     int len = name.length();
423     
424     while (i < len) {
425       for (; i < len && Character.isWhitespace(name.charAt(i)); i++) {
426       }
427
428       cb.clear();
429
430       int ch;
431       for (; i < len && (ch = name.charAt(i)) != '=' && ch != ',' &&
432          ! Character.isWhitespace((char) ch); i++) {
433     cb.append((char) ch);
434       }
435
436       String JavaDoc key = cb.toString();
437
438       if (key.length() == 0) {
439     throw new IllegalArgumentException JavaDoc(L.l("`{0}' is an illegal name syntax.",
440                            name));
441       }
442
443       for (; i < len && Character.isWhitespace(name.charAt(i)); i++) {
444       }
445
446       if (len <= i || (ch = name.charAt(i)) == ',') {
447     properties.put(key, "");
448       }
449       else if (ch == '=') {
450     for (i++; i < len && Character.isWhitespace(name.charAt(i)); i++) {
451     }
452
453     if (len <= i || (ch = name.charAt(i)) == ',') {
454       properties.put(key, "");
455     }
456     else if (ch == '"' || ch == '\'') {
457       int end = ch;
458       cb.clear();
459       
460       for (i++; i < len && (ch = name.charAt(i)) != end; i++) {
461         if (ch == '\\') {
462           ch = name.charAt(++i);
463           cb.append((char) ch);
464         }
465         else
466           cb.append((char) ch);
467       }
468
469       if (ch != end)
470         throw new IllegalArgumentException JavaDoc(L.l("`{0}' is an illegal name syntax.",
471                            name));
472
473       String JavaDoc value = cb.toString();
474
475       properties.put(key, value);
476     }
477     else {
478       cb.clear();
479       
480       for (; i < len && (ch = name.charAt(i)) != ','; i++)
481         cb.append((char) ch);
482
483       properties.put(key, cb.toString());
484     }
485       }
486       else {
487     throw new IllegalArgumentException JavaDoc(L.l("`{0}' is an illegal name syntax.",
488                            name));
489       }
490
491       for (; i < len && Character.isWhitespace(name.charAt(i)); i++) {
492       }
493       
494       if (i < len && name.charAt(i) != ',')
495     throw new IllegalArgumentException JavaDoc(L.l("`{0}' is an illegal name syntax.",
496                            name));
497
498       i++;
499     }
500   }
501
502   /**
503    * Creates the clean name
504    */

505   public static ObjectName getObjectName(String JavaDoc domain,
506                      Map JavaDoc<String JavaDoc,String JavaDoc> properties)
507     throws MalformedObjectNameException
508   {
509     StringBuilder JavaDoc cb = new StringBuilder JavaDoc();
510     cb.append(domain);
511     cb.append(':');
512
513     boolean isFirst = true;
514
515     // sort type first
516

517     String JavaDoc type = properties.get("type");
518     if (type != null) {
519       cb.append("type=");
520       if (type.matches("[,=:\"*?]"))
521     type = ObjectName.quote(type);
522       cb.append(type);
523
524       isFirst = false;
525     }
526
527     for (String JavaDoc key : properties.keySet()) {
528       if (key.equals("type"))
529     continue;
530       
531       if (! isFirst)
532     cb.append(',');
533       isFirst = false;
534
535       cb.append(key);
536       cb.append('=');
537
538       String JavaDoc value = properties.get(key);
539
540       if (value.length() == 0 || value.matches("[,=:\"*?]"))
541     value = ObjectName.quote(value);
542       
543       cb.append(value);
544     }
545
546     return new ObjectName(cb.toString());
547   }
548
549   /**
550    * Returns the local view.
551    */

552   /*
553   public static MBeanView getLocalView()
554   {
555     MBeanContext context = MBeanContext.getLocal();
556
557     return context.getView();
558   }
559   */

560
561   /**
562    * Returns the local view.
563    */

564   /*
565   public static MBeanView getLocalView(ClassLoader loader)
566   {
567     MBeanContext context = MBeanContext.getLocal(loader);
568
569     return context.getView();
570   }
571   */

572
573   /**
574    * Returns the local manged object.
575    */

576   public static Object JavaDoc find(String JavaDoc localName)
577     throws MalformedObjectNameException
578   {
579     return find(getMBeanServer().getContext().getObjectName(localName));
580   }
581
582   /**
583    * Returns the local manged object.
584    */

585   public static Object JavaDoc find(ObjectName name)
586   {
587     return find(name, Thread.currentThread().getContextClassLoader());
588   }
589
590   /**
591    * Returns the local manged object.
592    */

593   public static Object JavaDoc findGlobal(String JavaDoc localName)
594     throws MalformedObjectNameException
595   {
596     return findGlobal(getMBeanServer().getContext().getObjectName(localName));
597   }
598
599   /**
600    * Returns the local manged object.
601    */

602   public static Object JavaDoc findGlobal(ObjectName name)
603   {
604     return find(name, ClassLoader.getSystemClassLoader(), getGlobalMBeanServer());
605   }
606
607   /**
608    * Returns the local manged object.
609    */

610   public static Object JavaDoc find(ObjectName name, ClassLoader JavaDoc loader)
611   {
612     return find(name, loader, getMBeanServer());
613   }
614
615   /**
616    * Returns the local manged object.
617    */

618   public static Object JavaDoc find(ObjectName name,
619                 ClassLoader JavaDoc loader,
620                 MBeanServer mbeanServer)
621   {
622     try {
623       ObjectInstance obj = mbeanServer.getObjectInstance(name);
624
625       if (obj == null)
626     return null;
627
628       String JavaDoc className = obj.getClassName();
629
630       Class JavaDoc cl = Class.forName(className, false, loader);
631
632       Class JavaDoc ifc;
633       
634       if (cl.isInterface())
635     ifc = cl;
636       else
637     ifc = getMBeanInterface(cl);
638
639       if (ifc == null)
640     return null;
641
642       boolean isBroadcast = true;
643
644       Object JavaDoc proxy;
645
646       proxy = JmxInvocationHandler.newProxyInstance(mbeanServer,
647                             loader,
648                             name,
649                             ifc,
650                             true);
651
652       return proxy;
653     } catch (InstanceNotFoundException e) {
654       log.log(Level.FINE, e.toString(), e);
655       return null;
656     } catch (ClassNotFoundException JavaDoc e) {
657       log.log(Level.FINE, e.toString(), e);
658       return null;
659     }
660   }
661
662   /**
663    * Returns the local manged object.
664    */

665   public static ArrayList JavaDoc<Object JavaDoc> query(ObjectName namePattern)
666   {
667     Set JavaDoc<ObjectName> names = getMBeanServer().queryNames(namePattern, null);
668
669     ArrayList JavaDoc<Object JavaDoc> proxy = new ArrayList JavaDoc<Object JavaDoc>();
670     Iterator JavaDoc<ObjectName> iter = names.iterator();
671
672     while (iter.hasNext()) {
673       ObjectName name = iter.next();
674
675       proxy.add(find(name));
676     }
677     
678     return proxy;
679   }
680
681   /**
682    * Queues a task.
683    */

684   public static void queueAbsolute(TimerTask JavaDoc job, long time)
685   {
686     JobThread.queue(job, time);
687   }
688
689   /**
690    * Queues a task.
691    */

692   public static void queueRelative(TimerTask JavaDoc job, long delta)
693   {
694     queueAbsolute(job, Alarm.getCurrentTime() + delta);
695   }
696
697   /**
698    * Dequeues a task.
699    */

700   public static void dequeue(TimerTask JavaDoc job)
701   {
702     JobThread.dequeue(job);
703   }
704
705   // static
706
public Jmx() {}
707
708   private static void initStaticMBeans()
709   {
710     try {
711       Class JavaDoc cl = Class.forName("java.lang.Management.ManagementFactory");
712
713       Method JavaDoc method = cl.getMethod("getPlatformMBeanServer", new Class JavaDoc[0]);
714
715       method.invoke(null, new Object JavaDoc[0]);
716     } catch (Throwable JavaDoc e) {
717     }
718   }
719 }
720
721
Popular Tags