1:
37:
38: package ;
39:
40: import ;
41:
42: import ;
43: import ;
44: import ;
45: import ;
46: import ;
47: import ;
48: import ;
49: import ;
50: import ;
51:
52: import ;
53:
54: import ;
55: import ;
56: import ;
57:
58: import ;
59: import ;
60: import ;
61: import ;
62: import ;
63:
64: import ;
65:
66: import ;
67: import ;
68: import ;
69: import ;
70: import ;
71: import ;
72: import ;
73: import ;
74: import ;
75: import ;
76: import ;
77: import ;
78:
79: import ;
80: import ;
81:
82:
147: public class ManagementFactory
148: {
149:
150:
153: public static final String CLASS_LOADING_MXBEAN_NAME =
154: "java.lang:type=ClassLoading";
155:
156:
159: public static final String COMPILATION_MXBEAN_NAME =
160: "java.lang:type=Compilation";
161:
162:
165: public static final String GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE =
166: "java.lang:type=GarbageCollector";
167:
168:
171: public static final String MEMORY_MANAGER_MXBEAN_DOMAIN_TYPE =
172: "java.lang:type=MemoryManager";
173:
174:
177: public static final String MEMORY_MXBEAN_NAME =
178: "java.lang:type=Memory";
179:
180:
183: public static final String MEMORY_POOL_MXBEAN_DOMAIN_TYPE =
184: "java.lang:type=MemoryPool";
185:
186:
189: public static final String OPERATING_SYSTEM_MXBEAN_NAME =
190: "java.lang:type=OperatingSystem";
191:
192:
195: public static final String RUNTIME_MXBEAN_NAME =
196: "java.lang:type=Runtime";
197:
198:
201: public static final String THREAD_MXBEAN_NAME =
202: "java.lang:type=Threading";
203:
204:
207: private static OperatingSystemMXBean osBean;
208:
209:
212: private static RuntimeMXBean runtimeBean;
213:
214:
217: private static ClassLoadingMXBean classLoadingBean;
218:
219:
222: private static ThreadMXBean threadBean;
223:
224:
227: private static MemoryMXBean memoryBean;
228:
229:
232: private static CompilationMXBean compilationBean;
233:
234:
237: private static MBeanServer platformServer;
238:
239:
242: private ManagementFactory() {}
243:
244:
251: public static OperatingSystemMXBean getOperatingSystemMXBean()
252: {
253: if (osBean == null)
254: try
255: {
256: osBean = new OperatingSystemMXBeanImpl();
257: }
258: catch (NotCompliantMBeanException e)
259: {
260: throw new InternalError("The GNU implementation of the " +
261: "operating system bean is not a " +
262: "compliant management bean.");
263: }
264: return osBean;
265: }
266:
267:
274: public static RuntimeMXBean getRuntimeMXBean()
275: {
276: if (runtimeBean == null)
277: try
278: {
279: runtimeBean = new RuntimeMXBeanImpl();
280: }
281: catch (NotCompliantMBeanException e)
282: {
283: throw new InternalError("The GNU implementation of the " +
284: "runtime bean is not a compliant " +
285: "management bean.");
286: }
287: return runtimeBean;
288: }
289:
290:
297: public static ClassLoadingMXBean getClassLoadingMXBean()
298: {
299: if (classLoadingBean == null)
300: try
301: {
302: classLoadingBean = new ClassLoadingMXBeanImpl();
303: }
304: catch (NotCompliantMBeanException e)
305: {
306: throw new InternalError("The GNU implementation of the " +
307: "class loading bean is not a " +
308: "compliant management bean.");
309: }
310: return classLoadingBean;
311: }
312:
313:
320: public static ThreadMXBean getThreadMXBean()
321: {
322: if (threadBean == null)
323: try
324: {
325: threadBean = new ThreadMXBeanImpl();
326: }
327: catch (NotCompliantMBeanException e)
328: {
329: throw new InternalError("The GNU implementation of the " +
330: "thread bean is not a compliant " +
331: "management bean.");
332: }
333: return threadBean;
334: }
335:
336:
343: public static MemoryMXBean getMemoryMXBean()
344: {
345: if (memoryBean == null)
346: try
347: {
348: memoryBean = new MemoryMXBeanImpl();
349: }
350: catch (NotCompliantMBeanException e)
351: {
352: throw new InternalError("The GNU implementation of the " +
353: "memory bean is not a compliant " +
354: "management bean.");
355: }
356: return memoryBean;
357: }
358:
359:
369: public static CompilationMXBean getCompilationMXBean()
370: {
371: if (compilationBean == null &&
372: SystemProperties.getProperty("gnu.java.compiler.name") != null)
373: try
374: {
375: compilationBean = new CompilationMXBeanImpl();
376: }
377: catch (NotCompliantMBeanException e)
378: {
379: throw new InternalError("The GNU implementation of the " +
380: "compilation bean is not a compliant " +
381: "management bean.");
382: }
383: return compilationBean;
384: }
385:
386:
393: public static List<MemoryPoolMXBean> getMemoryPoolMXBeans()
394: {
395: List<MemoryPoolMXBean> poolBeans =
396: new ArrayList<MemoryPoolMXBean>();
397: String[] names = VMManagementFactory.getMemoryPoolNames();
398: for (int a = 0; a < names.length; ++a)
399: try
400: {
401: poolBeans.add(new MemoryPoolMXBeanImpl(names[a]));
402: }
403: catch (NotCompliantMBeanException e)
404: {
405: throw new InternalError("The GNU implementation of the " +
406: "memory pool bean, " + a + ", is " +
407: "not a compliant management bean.");
408: }
409: return poolBeans;
410: }
411:
412:
419: public static List<MemoryManagerMXBean> getMemoryManagerMXBeans()
420: {
421: List<MemoryManagerMXBean> managerBeans =
422: new ArrayList<MemoryManagerMXBean>();
423: String[] names = VMManagementFactory.getMemoryManagerNames();
424: for (int a = 0; a < names.length; ++a)
425: try
426: {
427: managerBeans.add(new MemoryManagerMXBeanImpl(names[a]));
428: }
429: catch (NotCompliantMBeanException e)
430: {
431: throw new InternalError("The GNU implementation of the " +
432: "memory manager bean, " + a + ", is " +
433: "not a compliant management bean.");
434: }
435: managerBeans.addAll(getGarbageCollectorMXBeans());
436: return managerBeans;
437: }
438:
439:
446: public static List<GarbageCollectorMXBean> getGarbageCollectorMXBeans()
447: {
448: List<GarbageCollectorMXBean> gcBeans =
449: new ArrayList<GarbageCollectorMXBean>();
450: String[] names = VMManagementFactory.getGarbageCollectorNames();
451: for (int a = 0; a < names.length; ++a)
452: try
453: {
454: gcBeans.add(new GarbageCollectorMXBeanImpl(names[a]));
455: }
456: catch (NotCompliantMBeanException e)
457: {
458: throw new InternalError("The GNU implementation of the " +
459: "garbage collector bean, " + a +
460: ", is not a compliant management " +
461: "bean.");
462: }
463: return gcBeans;
464: }
465:
466:
489: public static MBeanServer getPlatformMBeanServer()
490: {
491: if (platformServer == null)
492: {
493: platformServer = MBeanServerFactory.createMBeanServer();
494: try
495: {
496: platformServer.registerMBean(getOperatingSystemMXBean(),
497: new ObjectName(OPERATING_SYSTEM_MXBEAN_NAME));
498: platformServer.registerMBean(getRuntimeMXBean(),
499: new ObjectName(RUNTIME_MXBEAN_NAME));
500: platformServer.registerMBean(getClassLoadingMXBean(),
501: new ObjectName(CLASS_LOADING_MXBEAN_NAME));
502: platformServer.registerMBean(getThreadMXBean(),
503: new ObjectName(THREAD_MXBEAN_NAME));
504: platformServer.registerMBean(getMemoryMXBean(),
505: new ObjectName(MEMORY_MXBEAN_NAME));
506: CompilationMXBean compBean = getCompilationMXBean();
507: if (compBean != null)
508: platformServer.registerMBean(compBean,
509: new ObjectName(COMPILATION_MXBEAN_NAME));
510: Iterator beans = getMemoryPoolMXBeans().iterator();
511: while (beans.hasNext())
512: {
513: MemoryPoolMXBean bean = (MemoryPoolMXBean) beans.next();
514: platformServer.registerMBean(bean,
515: new ObjectName(MEMORY_POOL_MXBEAN_DOMAIN_TYPE +
516: ",name=" +
517: bean.getName()));
518: }
519: beans = getMemoryManagerMXBeans().iterator();
520: while (beans.hasNext())
521: {
522: MemoryManagerMXBean bean = (MemoryManagerMXBean) beans.next();
523: platformServer.registerMBean(bean,
524: new ObjectName(MEMORY_MANAGER_MXBEAN_DOMAIN_TYPE +
525: ",name=" +
526: bean.getName()));
527: }
528: beans = getGarbageCollectorMXBeans().iterator();
529: while (beans.hasNext())
530: {
531: GarbageCollectorMXBean bean = (GarbageCollectorMXBean) beans.next();
532: platformServer.registerMBean(bean,
533: new ObjectName(GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE +
534: ",name=" +
535: bean.getName()));
536: }
537: platformServer.registerMBean(LogManager.getLoggingMXBean(),
538: new ObjectName(LogManager.LOGGING_MXBEAN_NAME));
539: }
540: catch (InstanceAlreadyExistsException e)
541: {
542: throw (Error)
543: (new InternalError("One of the management beans is " +
544: "already registered.").initCause(e));
545: }
546: catch (MBeanRegistrationException e)
547: {
548: throw (Error)
549: (new InternalError("One of the management beans' preRegister " +
550: "methods threw an exception.").initCause(e));
551: }
552: catch (NotCompliantMBeanException e)
553: {
554: throw (Error)
555: (new InternalError("One of the management beans is " +
556: "not compliant.").initCause(e));
557: }
558: catch (MalformedObjectNameException e)
559: {
560: throw (Error)
561: (new InternalError("The object name of a management bean is " +
562: "not compliant.").initCause(e));
563: }
564: }
565: return platformServer;
566: }
567:
568:
602: public static <T> T newPlatformMXBeanProxy(MBeanServerConnection connection,
603: String mxbeanName,
604: Class<T> mxbeanInterface)
605: throws IOException
606: {
607: if (!(mxbeanName.equals(CLASS_LOADING_MXBEAN_NAME) ||
608: mxbeanName.equals(COMPILATION_MXBEAN_NAME) ||
609: mxbeanName.startsWith(GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE) ||
610: mxbeanName.startsWith(MEMORY_MANAGER_MXBEAN_DOMAIN_TYPE) ||
611: mxbeanName.equals(MEMORY_MXBEAN_NAME) ||
612: mxbeanName.startsWith(MEMORY_POOL_MXBEAN_DOMAIN_TYPE) ||
613: mxbeanName.equals(OPERATING_SYSTEM_MXBEAN_NAME) ||
614: mxbeanName.equals(RUNTIME_MXBEAN_NAME) ||
615: mxbeanName.equals(THREAD_MXBEAN_NAME)))
616: {
617: throw new IllegalArgumentException("The named bean, " + mxbeanName +
618: ", is not a platform name.");
619: }
620: if ((mxbeanName.equals(CLASS_LOADING_MXBEAN_NAME) &&
621: mxbeanInterface != ClassLoadingMXBean.class) ||
622: (mxbeanName.equals(COMPILATION_MXBEAN_NAME) &&
623: mxbeanInterface != CompilationMXBean.class) ||
624: (mxbeanName.startsWith(GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE) &&
625: mxbeanInterface != GarbageCollectorMXBean.class) ||
626: (mxbeanName.startsWith(MEMORY_MANAGER_MXBEAN_DOMAIN_TYPE) &&
627: mxbeanInterface != MemoryManagerMXBean.class) ||
628: (mxbeanName.equals(MEMORY_MXBEAN_NAME) &&
629: mxbeanInterface != MemoryMXBean.class) ||
630: (mxbeanName.startsWith(MEMORY_POOL_MXBEAN_DOMAIN_TYPE) &&
631: mxbeanInterface != MemoryPoolMXBean.class) ||
632: (mxbeanName.equals(OPERATING_SYSTEM_MXBEAN_NAME) &&
633: mxbeanInterface != OperatingSystemMXBean.class) ||
634: (mxbeanName.equals(RUNTIME_MXBEAN_NAME) &&
635: mxbeanInterface != RuntimeMXBean.class) ||
636: (mxbeanName.equals(THREAD_MXBEAN_NAME) &&
637: mxbeanInterface != ThreadMXBean.class))
638: throw new IllegalArgumentException("The interface, " + mxbeanInterface +
639: ", does not match the bean, " + mxbeanName);
640: ObjectName bean;
641: try
642: {
643: bean = new ObjectName(mxbeanName);
644: }
645: catch (MalformedObjectNameException e)
646: {
647: throw new IllegalArgumentException("The named bean is invalid.");
648: }
649: if (!(connection.isRegistered(bean)))
650: throw new IllegalArgumentException("The bean is not registered on this connection.");
651: Class[] interfaces;
652: if (mxbeanName.equals(MEMORY_MXBEAN_NAME))
653: interfaces = new Class[] { mxbeanInterface, NotificationEmitter.class };
654: else
655: interfaces = new Class[] { mxbeanInterface };
656: return (T) Proxy.newProxyInstance(mxbeanInterface.getClassLoader(),
657: interfaces,
658: new ManagementInvocationHandler(connection, bean));
659: }
660:
661:
669: private static class ManagementInvocationHandler
670: implements InvocationHandler
671: {
672:
673:
676: private MBeanServerConnection conn;
677:
678:
681: private ObjectName bean;
682:
683:
690: public ManagementInvocationHandler(MBeanServerConnection conn,
691: ObjectName bean)
692: throws IOException
693: {
694: this.conn = conn;
695: this.bean = bean;
696: }
697:
698:
713: public Object invoke(Object proxy, Method method, Object[] args)
714: throws Throwable
715: {
716: String name = method.getName();
717: if (name.equals("toString"))
718: return "Proxy for " + bean + " using " + conn;
719: if (name.equals("addNotificationListener"))
720: {
721: conn.addNotificationListener(bean,
722: (NotificationListener) args[0],
723: (NotificationFilter) args[1],
724: args[2]);
725: return null;
726: }
727: if (name.equals("getNotificationInfo"))
728: return conn.getMBeanInfo(bean).getNotifications();
729: if (name.equals("removeNotificationListener"))
730: {
731: if (args.length == 1)
732: conn.removeNotificationListener(bean,
733: (NotificationListener)
734: args[0]);
735: else
736: conn.removeNotificationListener(bean,
737: (NotificationListener)
738: args[0],
739: (NotificationFilter)
740: args[1], args[2]);
741: return null;
742: }
743: String attrib = null;
744: if (name.startsWith("get"))
745: attrib = name.substring(3);
746: else if (name.startsWith("is"))
747: attrib = name.substring(2);
748: if (attrib != null)
749: return translate(conn.getAttribute(bean, attrib), method);
750: else if (name.startsWith("set"))
751: {
752: conn.setAttribute(bean, new Attribute(name.substring(3),
753: args[0]));
754: return null;
755: }
756: else
757: return translate(conn.invoke(bean, name, args, null), method);
758: }
759:
760:
770: private final Object translate(Object otype, Method method)
771: throws Throwable
772: {
773: Class<?> returnType = method.getReturnType();
774: if (returnType.isEnum())
775: {
776: String ename = (String) otype;
777: Enum[] constants = (Enum[]) returnType.getEnumConstants();
778: for (Enum c : constants)
779: if (c.name().equals(ename))
780: return c;
781: }
782: if (List.class.isAssignableFrom(returnType))
783: {
784: Object[] elems = (Object[]) otype;
785: List l = new ArrayList(elems.length);
786: for (Object elem : elems)
787: l.add(elem);
788: return l;
789: }
790: if (Map.class.isAssignableFrom(returnType))
791: {
792: TabularData data = (TabularData) otype;
793: Map m = new HashMap(data.size());
794: for (Object val : data.values())
795: {
796: CompositeData vals = (CompositeData) val;
797: m.put(vals.get("key"), vals.get("value"));
798: }
799: return m;
800: }
801: try
802: {
803: Method m = returnType.getMethod("from",
804: new Class[]
805: { CompositeData.class });
806: return m.invoke(null, (CompositeData) otype);
807: }
808: catch (NoSuchMethodException e)
809: {
810:
812: }
813: return otype;
814: }
815:
816: }
817: }