View Javadoc
1   /*
2    * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4    *
5    * This code is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU General Public License version 2 only, as
7    * published by the Free Software Foundation.  Oracle designates this
8    * particular file as subject to the "Classpath" exception as provided
9    * by Oracle in the LICENSE file that accompanied this code.
10   *
11   * This code is distributed in the hope that it will be useful, but WITHOUT
12   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14   * version 2 for more details (a copy is included in the LICENSE file that
15   * accompanied this code).
16   *
17   * You should have received a copy of the GNU General Public License version
18   * 2 along with this work; if not, write to the Free Software Foundation,
19   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20   *
21   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22   * or visit www.oracle.com if you need additional information or have any
23   * questions.
24   */
25  
26  package java.lang.management;
27  
28  import java.util.ArrayList;
29  import java.util.Collections;
30  import java.util.List;
31  import java.util.HashSet;
32  import java.util.HashMap;
33  import java.util.Map;
34  import java.util.Set;
35  import javax.management.MBeanServerConnection;
36  import javax.management.ObjectName;
37  
38  import com.sun.management.HotSpotDiagnosticMXBean;
39  import com.sun.management.UnixOperatingSystemMXBean;
40  
41  import sun.management.ManagementFactoryHelper;
42  import sun.management.Util;
43  
44  /**
45   * This enum class defines the list of platform components
46   * that provides monitoring and management support.
47   * Each enum represents one MXBean interface. A MXBean
48   * instance could implement one or more MXBean interfaces.
49   *
50   * For example, com.sun.management.GarbageCollectorMXBean
51   * extends java.lang.management.GarbageCollectorMXBean
52   * and there is one set of garbage collection MXBean instances,
53   * each of which implements both c.s.m. and j.l.m. interfaces.
54   * There are two separate enums GARBAGE_COLLECTOR
55   * and SUN_GARBAGE_COLLECTOR so that ManagementFactory.getPlatformMXBeans(Class)
56   * will return the list of MXBeans of the specified type.
57   *
58   * To add a new MXBean interface for the Java platform,
59   * add a new enum constant and implement the MXBeanFetcher.
60   */
61  enum PlatformComponent {
62  
63      /**
64       * Class loading system of the Java virtual machine.
65       */
66      CLASS_LOADING(
67          "java.lang.management.ClassLoadingMXBean",
68          "java.lang", "ClassLoading", defaultKeyProperties(),
69          true, // singleton
70          new MXBeanFetcher<ClassLoadingMXBean>() {
71              public List<ClassLoadingMXBean> getMXBeans() {
72                  return Collections.singletonList(ManagementFactoryHelper.getClassLoadingMXBean());
73              }
74          }),
75  
76      /**
77       * Compilation system of the Java virtual machine.
78       */
79      COMPILATION(
80          "java.lang.management.CompilationMXBean",
81          "java.lang", "Compilation", defaultKeyProperties(),
82          true, // singleton
83          new MXBeanFetcher<CompilationMXBean>() {
84              public List<CompilationMXBean> getMXBeans() {
85                  CompilationMXBean m = ManagementFactoryHelper.getCompilationMXBean();
86                  if (m == null) {
87                     return Collections.emptyList();
88                  } else {
89                     return Collections.singletonList(m);
90                  }
91              }
92          }),
93  
94      /**
95       * Memory system of the Java virtual machine.
96       */
97      MEMORY(
98          "java.lang.management.MemoryMXBean",
99          "java.lang", "Memory", defaultKeyProperties(),
100         true, // singleton
101         new MXBeanFetcher<MemoryMXBean>() {
102             public List<MemoryMXBean> getMXBeans() {
103                 return Collections.singletonList(ManagementFactoryHelper.getMemoryMXBean());
104             }
105         }),
106 
107     /**
108      * Garbage Collector in the Java virtual machine.
109      */
110     GARBAGE_COLLECTOR(
111         "java.lang.management.GarbageCollectorMXBean",
112         "java.lang", "GarbageCollector", keyProperties("name"),
113         false, // zero or more instances
114         new MXBeanFetcher<GarbageCollectorMXBean>() {
115             public List<GarbageCollectorMXBean> getMXBeans() {
116                 return ManagementFactoryHelper.
117                            getGarbageCollectorMXBeans();
118             }
119         }),
120 
121     /**
122      * Memory manager in the Java virtual machine.
123      */
124     MEMORY_MANAGER(
125         "java.lang.management.MemoryManagerMXBean",
126         "java.lang", "MemoryManager", keyProperties("name"),
127         false, // zero or more instances
128         new MXBeanFetcher<MemoryManagerMXBean>() {
129             public List<MemoryManagerMXBean> getMXBeans() {
130                 return ManagementFactoryHelper.getMemoryManagerMXBeans();
131             }
132         },
133         GARBAGE_COLLECTOR),
134 
135     /**
136      * Memory pool in the Java virtual machine.
137      */
138     MEMORY_POOL(
139         "java.lang.management.MemoryPoolMXBean",
140         "java.lang", "MemoryPool", keyProperties("name"),
141         false, // zero or more instances
142         new MXBeanFetcher<MemoryPoolMXBean>() {
143             public List<MemoryPoolMXBean> getMXBeans() {
144                 return ManagementFactoryHelper.getMemoryPoolMXBeans();
145             }
146         }),
147 
148     /**
149      * Operating system on which the Java virtual machine is running
150      */
151     OPERATING_SYSTEM(
152         "java.lang.management.OperatingSystemMXBean",
153         "java.lang", "OperatingSystem", defaultKeyProperties(),
154         true, // singleton
155         new MXBeanFetcher<OperatingSystemMXBean>() {
156             public List<OperatingSystemMXBean> getMXBeans() {
157                 return Collections.singletonList(ManagementFactoryHelper.getOperatingSystemMXBean());
158             }
159         }),
160 
161     /**
162      * Runtime system of the Java virtual machine.
163      */
164     RUNTIME(
165         "java.lang.management.RuntimeMXBean",
166         "java.lang", "Runtime", defaultKeyProperties(),
167         true, // singleton
168         new MXBeanFetcher<RuntimeMXBean>() {
169             public List<RuntimeMXBean> getMXBeans() {
170                 return Collections.singletonList(ManagementFactoryHelper.getRuntimeMXBean());
171             }
172         }),
173 
174     /**
175      * Threading system of the Java virtual machine.
176      */
177     THREADING(
178         "java.lang.management.ThreadMXBean",
179         "java.lang", "Threading", defaultKeyProperties(),
180         true, // singleton
181         new MXBeanFetcher<ThreadMXBean>() {
182             public List<ThreadMXBean> getMXBeans() {
183                 return Collections.singletonList(ManagementFactoryHelper.getThreadMXBean());
184             }
185         }),
186 
187 
188     /**
189      * Logging facility.
190      */
191     LOGGING(
192         "java.lang.management.PlatformLoggingMXBean",
193         "java.util.logging", "Logging", defaultKeyProperties(),
194         true, // singleton
195         new MXBeanFetcher<PlatformLoggingMXBean>() {
196             public List<PlatformLoggingMXBean> getMXBeans() {
197                 PlatformLoggingMXBean m = ManagementFactoryHelper.getPlatformLoggingMXBean();
198                 if (m == null) {
199                    return Collections.emptyList();
200                 } else {
201                    return Collections.singletonList(m);
202                 }
203             }
204         }),
205 
206     /**
207      * Buffer pools.
208      */
209     BUFFER_POOL(
210         "java.lang.management.BufferPoolMXBean",
211         "java.nio", "BufferPool", keyProperties("name"),
212         false, // zero or more instances
213         new MXBeanFetcher<BufferPoolMXBean>() {
214             public List<BufferPoolMXBean> getMXBeans() {
215                 return ManagementFactoryHelper.getBufferPoolMXBeans();
216             }
217         }),
218 
219 
220     // Sun Platform Extension
221 
222     /**
223      * Sun extension garbage collector that performs collections in cycles.
224      */
225     SUN_GARBAGE_COLLECTOR(
226         "com.sun.management.GarbageCollectorMXBean",
227         "java.lang", "GarbageCollector", keyProperties("name"),
228         false, // zero or more instances
229         new MXBeanFetcher<com.sun.management.GarbageCollectorMXBean>() {
230             public List<com.sun.management.GarbageCollectorMXBean> getMXBeans() {
231                 return getGcMXBeanList(com.sun.management.GarbageCollectorMXBean.class);
232             }
233         }),
234 
235     /**
236      * Sun extension operating system on which the Java virtual machine
237      * is running.
238      */
239     SUN_OPERATING_SYSTEM(
240         "com.sun.management.OperatingSystemMXBean",
241         "java.lang", "OperatingSystem", defaultKeyProperties(),
242         true, // singleton
243         new MXBeanFetcher<com.sun.management.OperatingSystemMXBean>() {
244             public List<com.sun.management.OperatingSystemMXBean> getMXBeans() {
245                 return getOSMXBeanList(com.sun.management.OperatingSystemMXBean.class);
246             }
247         }),
248 
249     /**
250      * Unix operating system.
251      */
252     SUN_UNIX_OPERATING_SYSTEM(
253         "com.sun.management.UnixOperatingSystemMXBean",
254         "java.lang", "OperatingSystem", defaultKeyProperties(),
255         true, // singleton
256         new MXBeanFetcher<UnixOperatingSystemMXBean>() {
257             public List<UnixOperatingSystemMXBean> getMXBeans() {
258                 return getOSMXBeanList(com.sun.management.UnixOperatingSystemMXBean.class);
259             }
260         }),
261 
262     /**
263      * Diagnostic support for the HotSpot Virtual Machine.
264      */
265     HOTSPOT_DIAGNOSTIC(
266         "com.sun.management.HotSpotDiagnosticMXBean",
267         "com.sun.management", "HotSpotDiagnostic", defaultKeyProperties(),
268         true, // singleton
269         new MXBeanFetcher<HotSpotDiagnosticMXBean>() {
270             public List<HotSpotDiagnosticMXBean> getMXBeans() {
271                 return Collections.singletonList(ManagementFactoryHelper.getDiagnosticMXBean());
272             }
273         });
274 
275 
276     /**
277      * A task that returns the MXBeans for a component.
278      */
279     interface MXBeanFetcher<T extends PlatformManagedObject> {
280         public List<T> getMXBeans();
281     }
282 
283     /*
284      * Returns a list of the GC MXBeans of the given type.
285      */
286     private static <T extends GarbageCollectorMXBean>
287             List<T> getGcMXBeanList(Class<T> gcMXBeanIntf) {
288         List<GarbageCollectorMXBean> list =
289             ManagementFactoryHelper.getGarbageCollectorMXBeans();
290         List<T> result = new ArrayList<>(list.size());
291         for (GarbageCollectorMXBean m : list) {
292             if (gcMXBeanIntf.isInstance(m)) {
293                 result.add(gcMXBeanIntf.cast(m));
294             }
295         }
296         return result;
297     }
298 
299     /*
300      * Returns the OS mxbean instance of the given type.
301      */
302     private static <T extends OperatingSystemMXBean>
303             List<T> getOSMXBeanList(Class<T> osMXBeanIntf) {
304         OperatingSystemMXBean m =
305             ManagementFactoryHelper.getOperatingSystemMXBean();
306         if (osMXBeanIntf.isInstance(m)) {
307             return Collections.singletonList(osMXBeanIntf.cast(m));
308         } else {
309             return Collections.emptyList();
310         }
311     }
312 
313     private final String mxbeanInterfaceName;
314     private final String domain;
315     private final String type;
316     private final Set<String> keyProperties;
317     private final MXBeanFetcher<?> fetcher;
318     private final PlatformComponent[] subComponents;
319     private final boolean singleton;
320 
321     private PlatformComponent(String intfName,
322                               String domain, String type,
323                               Set<String> keyProperties,
324                               boolean singleton,
325                               MXBeanFetcher<?> fetcher,
326                               PlatformComponent... subComponents) {
327         this.mxbeanInterfaceName = intfName;
328         this.domain = domain;
329         this.type = type;
330         this.keyProperties = keyProperties;
331         this.singleton = singleton;
332         this.fetcher = fetcher;
333         this.subComponents = subComponents;
334     }
335 
336     private static Set<String> defaultKeyProps;
337     private static Set<String> defaultKeyProperties() {
338         if (defaultKeyProps == null) {
339             defaultKeyProps = Collections.singleton("type");
340         }
341         return defaultKeyProps;
342     }
343 
344     private static Set<String> keyProperties(String... keyNames) {
345         Set<String> set = new HashSet<>();
346         set.add("type");
347         for (String s : keyNames) {
348             set.add(s);
349         }
350         return set;
351     }
352 
353     boolean isSingleton() {
354         return singleton;
355     }
356 
357     String getMXBeanInterfaceName() {
358         return mxbeanInterfaceName;
359     }
360 
361     @SuppressWarnings("unchecked")
362     Class<? extends PlatformManagedObject> getMXBeanInterface() {
363         try {
364             // Lazy loading the MXBean interface only when it is needed
365             return (Class<? extends PlatformManagedObject>)
366                        Class.forName(mxbeanInterfaceName, false,
367                                      PlatformManagedObject.class.getClassLoader());
368         } catch (ClassNotFoundException x) {
369             throw new AssertionError(x);
370         }
371     }
372 
373     @SuppressWarnings("unchecked")
374     <T extends PlatformManagedObject>
375         List<T> getMXBeans(Class<T> mxbeanInterface)
376     {
377         return (List<T>) fetcher.getMXBeans();
378     }
379 
380     <T extends PlatformManagedObject> T getSingletonMXBean(Class<T> mxbeanInterface)
381     {
382         if (!singleton)
383             throw new IllegalArgumentException(mxbeanInterfaceName +
384                 " can have zero or more than one instances");
385 
386         List<T> list = getMXBeans(mxbeanInterface);
387         assert list.size() == 1;
388         return list.isEmpty() ? null : list.get(0);
389     }
390 
391     <T extends PlatformManagedObject>
392             T getSingletonMXBean(MBeanServerConnection mbs, Class<T> mxbeanInterface)
393         throws java.io.IOException
394     {
395         if (!singleton)
396             throw new IllegalArgumentException(mxbeanInterfaceName +
397                 " can have zero or more than one instances");
398 
399         // ObjectName of a singleton MXBean contains only domain and type
400         assert keyProperties.size() == 1;
401         String on = domain + ":type=" + type;
402         return ManagementFactory.newPlatformMXBeanProxy(mbs,
403                                                         on,
404                                                         mxbeanInterface);
405     }
406 
407     <T extends PlatformManagedObject>
408             List<T> getMXBeans(MBeanServerConnection mbs, Class<T> mxbeanInterface)
409         throws java.io.IOException
410     {
411         List<T> result = new ArrayList<>();
412         for (ObjectName on : getObjectNames(mbs)) {
413             result.add(ManagementFactory.
414                 newPlatformMXBeanProxy(mbs,
415                                        on.getCanonicalName(),
416                                        mxbeanInterface)
417             );
418         }
419         return result;
420     }
421 
422     private Set<ObjectName> getObjectNames(MBeanServerConnection mbs)
423         throws java.io.IOException
424     {
425         String domainAndType = domain + ":type=" + type;
426         if (keyProperties.size() > 1) {
427             // if there are more than 1 key properties (i.e. other than "type")
428             domainAndType += ",*";
429         }
430         ObjectName on = Util.newObjectName(domainAndType);
431         Set<ObjectName> set =  mbs.queryNames(on, null);
432         for (PlatformComponent pc : subComponents) {
433             set.addAll(pc.getObjectNames(mbs));
434         }
435         return set;
436     }
437 
438     // a map from MXBean interface name to PlatformComponent
439     private static Map<String, PlatformComponent> enumMap;
440     private static synchronized void ensureInitialized() {
441         if (enumMap == null) {
442             enumMap = new HashMap<>();
443             for (PlatformComponent pc: PlatformComponent.values()) {
444                 // Use String as the key rather than Class<?> to avoid
445                 // causing unnecessary class loading of management interface
446                 enumMap.put(pc.getMXBeanInterfaceName(), pc);
447             }
448         }
449     }
450 
451     static boolean isPlatformMXBean(String cn) {
452         ensureInitialized();
453         return enumMap.containsKey(cn);
454     }
455 
456     static <T extends PlatformManagedObject>
457         PlatformComponent getPlatformComponent(Class<T> mxbeanInterface)
458     {
459         ensureInitialized();
460         String cn = mxbeanInterface.getName();
461         PlatformComponent pc = enumMap.get(cn);
462         if (pc != null && pc.getMXBeanInterface() == mxbeanInterface)
463             return pc;
464         return null;
465     }
466 
467     private static final long serialVersionUID = 6992337162326171013L;
468 }