1 /*
   2  * Copyright (c) 2008, 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.Set;
  33 import java.util.logging.PlatformLoggingMXBean;
  34 import java.nio.BufferPoolMXBean;
  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         new MXBeanFetcher<ClassLoadingMXBean>() {
  70             public List<ClassLoadingMXBean> getMXBeans() {
  71                 return Collections.singletonList(ManagementFactoryHelper.getClassLoadingMXBean());
  72             }
  73         }),
  74 
  75     /**
  76      * Compilation system of the Java virtual machine.
  77      */
  78     COMPILATION(
  79         "java.lang.management.CompilationMXBean",
  80         "java.lang", "Compilation", defaultKeyProperties(),
  81         new MXBeanFetcher<CompilationMXBean>() {
  82             public List<CompilationMXBean> getMXBeans() {
  83                 CompilationMXBean m = ManagementFactoryHelper.getCompilationMXBean();
  84                 if (m == null) {
  85                    return Collections.emptyList();
  86                 } else {
  87                    return Collections.singletonList(m);
  88                 }
  89             }
  90         }),
  91 
  92     /**
  93      * Memory system of the Java virtual machine.
  94      */
  95     MEMORY(
  96         "java.lang.management.MemoryMXBean",
  97         "java.lang", "Memory", defaultKeyProperties(),
  98         new MXBeanFetcher<MemoryMXBean>() {
  99             public List<MemoryMXBean> getMXBeans() {
 100                 return Collections.singletonList(ManagementFactoryHelper.getMemoryMXBean());
 101             }
 102         }),
 103 
 104     /**
 105      * Garbage Collector in the Java virtual machine.
 106      */
 107     GARBAGE_COLLECTOR(
 108         "java.lang.management.GarbageCollectorMXBean",
 109         "java.lang", "GarbageCollector", keyProperties("name"),
 110         new MXBeanFetcher<GarbageCollectorMXBean>() {
 111             public List<GarbageCollectorMXBean> getMXBeans() {
 112                 return ManagementFactoryHelper.
 113                            getGarbageCollectorMXBeans();
 114             }
 115         }),
 116 
 117     /**
 118      * Memory manager in the Java virtual machine.
 119      */
 120     MEMORY_MANAGER(
 121         "java.lang.management.MemoryManagerMXBean",
 122         "java.lang", "MemoryManager", keyProperties("name"),
 123         new MXBeanFetcher<MemoryManagerMXBean>() {
 124             public List<MemoryManagerMXBean> getMXBeans() {
 125                 return ManagementFactoryHelper.getMemoryManagerMXBeans();
 126             }
 127         },
 128         GARBAGE_COLLECTOR),
 129 
 130     /**
 131      * Memory pool in the Java virtual machine.
 132      */
 133     MEMORY_POOL(
 134         "java.lang.management.MemoryPoolMXBean",
 135         "java.lang", "MemoryPool", keyProperties("name"),
 136         new MXBeanFetcher<MemoryPoolMXBean>() {
 137             public List<MemoryPoolMXBean> getMXBeans() {
 138                 return ManagementFactoryHelper.getMemoryPoolMXBeans();
 139             }
 140         }),
 141 
 142     /**
 143      * Operating system on which the Java virtual machine is running
 144      */
 145     OPERATING_SYSTEM(
 146         "java.lang.management.OperatingSystemMXBean",
 147         "java.lang", "OperatingSystem", defaultKeyProperties(),
 148         new MXBeanFetcher<OperatingSystemMXBean>() {
 149             public List<OperatingSystemMXBean> getMXBeans() {
 150                 return Collections.singletonList(ManagementFactoryHelper.getOperatingSystemMXBean());
 151             }
 152         }),
 153 
 154     /**
 155      * Runtime system of the Java virtual machine.
 156      */
 157     RUNTIME(
 158         "java.lang.management.RuntimeMXBean",
 159         "java.lang", "Runtime", defaultKeyProperties(),
 160         new MXBeanFetcher<RuntimeMXBean>() {
 161             public List<RuntimeMXBean> getMXBeans() {
 162                 return Collections.singletonList(ManagementFactoryHelper.getRuntimeMXBean());
 163             }
 164         }),
 165 
 166     /**
 167      * Threading system of the Java virtual machine.
 168      */
 169     THREADING(
 170         "java.lang.management.ThreadMXBean",
 171         "java.lang", "Threading", defaultKeyProperties(),
 172         new MXBeanFetcher<ThreadMXBean>() {
 173             public List<ThreadMXBean> getMXBeans() {
 174                 return Collections.singletonList(ManagementFactoryHelper.getThreadMXBean());
 175             }
 176         }),
 177 
 178 
 179     /**
 180      * Logging facility.
 181      */
 182     LOGGING(
 183         "java.util.logging.PlatformLoggingMXBean",
 184         "java.util.logging", "Logging", defaultKeyProperties(),
 185         new MXBeanFetcher<PlatformLoggingMXBean>() {
 186             public List<PlatformLoggingMXBean> getMXBeans() {
 187                 return ManagementFactoryHelper.getLoggingMXBean();
 188             }
 189         }),
 190 
 191     /**
 192      * Buffer pools.
 193      */
 194     BUFFER_POOL(
 195         "java.nio.BufferPoolMXBean",
 196         "java.nio", "BufferPool", keyProperties("name"),
 197         new MXBeanFetcher<BufferPoolMXBean>() {
 198             public List<BufferPoolMXBean> getMXBeans() {
 199                 return ManagementFactoryHelper.getBufferPoolMXBeans();
 200             }
 201         }),
 202 
 203 
 204     // Sun Platform Extension
 205 
 206     /**
 207      * Sun extension garbage collector that performs collections in cycles.
 208      */
 209     SUN_GARBAGE_COLLECTOR(
 210         "com.sun.management.GarbageCollectorMXBean",
 211         "java.lang", "GarbageCollector", keyProperties("name"),
 212         new MXBeanFetcher<com.sun.management.GarbageCollectorMXBean>() {
 213             public List<com.sun.management.GarbageCollectorMXBean> getMXBeans() {
 214                 return getGcMXBeanList(com.sun.management.GarbageCollectorMXBean.class);
 215             }
 216         }),
 217 
 218     /**
 219      * Sun extension operating system on which the Java virtual machine
 220      * is running.
 221      */
 222     SUN_OPERATING_SYSTEM(
 223         "com.sun.management.OperatingSystemMXBean",
 224         "java.lang", "OperatingSystem", defaultKeyProperties(),
 225         new MXBeanFetcher<com.sun.management.OperatingSystemMXBean>() {
 226             public List<com.sun.management.OperatingSystemMXBean> getMXBeans() {
 227                 return getOSMXBeanList(com.sun.management.OperatingSystemMXBean.class);
 228             }
 229         }),
 230 
 231     /**
 232      * Unix operating system.
 233      */
 234     SUN_UNIX_OPERATING_SYSTEM(
 235         "com.sun.management.UnixOperatingSystemMXBean",
 236         "java.lang", "OperatingSystem", defaultKeyProperties(),
 237         new MXBeanFetcher<UnixOperatingSystemMXBean>() {
 238             public List<UnixOperatingSystemMXBean> getMXBeans() {
 239                 return getOSMXBeanList(com.sun.management.UnixOperatingSystemMXBean.class);
 240             }
 241         }),
 242 
 243     /**
 244      * Diagnostic support for the HotSpot Virtual Machine.
 245      */
 246     HOTSPOT_DIAGNOSTIC(
 247         "com.sun.management.HotSpotDiagnosticMXBean",
 248         "com.sun.management", "HotSpotDiagnostic", defaultKeyProperties(),
 249         new MXBeanFetcher<HotSpotDiagnosticMXBean>() {
 250             public List<HotSpotDiagnosticMXBean> getMXBeans() {
 251                 return Collections.singletonList(ManagementFactoryHelper.getDiagnosticMXBean());
 252             }
 253         });
 254 
 255 
 256     /**
 257      * A task that returns the MXBeans for a component.
 258      */
 259     interface MXBeanFetcher<T extends PlatformManagedObject> {
 260         public List<T> getMXBeans();
 261     }
 262 
 263     /*
 264      * Returns a list of the GC MXBeans of the given type.
 265      */
 266     private static <T extends GarbageCollectorMXBean>
 267             List<T> getGcMXBeanList(Class<T> gcMXBeanIntf) {
 268         List<GarbageCollectorMXBean> list =
 269             ManagementFactoryHelper.getGarbageCollectorMXBeans();
 270         List<T> result = new ArrayList<>(list.size());
 271         for (GarbageCollectorMXBean m : list) {
 272             if (gcMXBeanIntf.isInstance(m)) {
 273                 result.add(gcMXBeanIntf.cast(m));
 274             }
 275         }
 276         return result;
 277     }
 278 
 279     /*
 280      * Returns the OS mxbean instance of the given type.
 281      */
 282     private static <T extends OperatingSystemMXBean>
 283             List<T> getOSMXBeanList(Class<T> osMXBeanIntf) {
 284         OperatingSystemMXBean m =
 285             ManagementFactoryHelper.getOperatingSystemMXBean();
 286         if (osMXBeanIntf.isInstance(m)) {
 287             return Collections.singletonList(osMXBeanIntf.cast(m));
 288         } else {
 289             return Collections.emptyList();
 290         }
 291     }
 292 
 293     private final String mxbeanInterfaceName;
 294     private final String domain;
 295     private final String type;
 296     private final Set<String> keyProperties;
 297     private final MXBeanFetcher fetcher;
 298     private final PlatformComponent[] subComponents;
 299 
 300     private PlatformComponent(String intfName,
 301                               String domain, String type,
 302                               Set<String> keyProperties,
 303                               MXBeanFetcher fetcher) {
 304         this.mxbeanInterfaceName = intfName;
 305         this.domain = domain;
 306         this.type = type;
 307         this.keyProperties = keyProperties;
 308         this.fetcher = fetcher;
 309         this.subComponents = new PlatformComponent[0];
 310     }
 311     private PlatformComponent(String intfName,
 312                               String domain, String type,
 313                               Set<String> keyProperties,
 314                               MXBeanFetcher fetcher,
 315                               PlatformComponent... subComponents) {
 316         this.mxbeanInterfaceName = intfName;
 317         this.domain = domain;
 318         this.type = type;
 319         this.keyProperties = keyProperties;
 320         this.fetcher = fetcher;
 321         this.subComponents = subComponents;
 322     }
 323 
 324     private static Set<String> defaultKeyProps;
 325     private static Set<String> defaultKeyProperties() {
 326         if (defaultKeyProps == null) {
 327             defaultKeyProps = Collections.singleton("type");
 328         }
 329         return defaultKeyProps;
 330     }
 331 
 332     private static Set<String> keyProperties(String... keyNames) {
 333         Set<String> set = new HashSet<>();
 334         set.add("type");
 335         for (String s : keyNames) {
 336             set.add(s);
 337         }
 338         return set;
 339     }
 340 
 341     String getMXBeanInterfaceName() {
 342         return mxbeanInterfaceName;
 343     }
 344 
 345     @SuppressWarnings("unchecked")
 346     Class<? extends PlatformManagedObject> getMXBeanInterface() {
 347         try {
 348             // Lazy loading the MXBean interface only when it is needed
 349             return (Class<? extends PlatformManagedObject>)
 350                        Class.forName(mxbeanInterfaceName, false, null);
 351         } catch (ClassNotFoundException x) {
 352             throw new AssertionError(x);
 353         }
 354     }
 355 
 356     @SuppressWarnings("unchecked")
 357     <T extends PlatformManagedObject>
 358         List<T> getMXBeans(Class<T> mxbeanInterface)
 359     {
 360         return fetcher.getMXBeans();
 361     }
 362 
 363     <T extends PlatformManagedObject>
 364         List<T> getMXBeans(MBeanServerConnection mbs, Class<T> mxbeanInterface)
 365         throws java.io.IOException
 366     {
 367         List<T> result = new ArrayList<>();
 368         for (ObjectName on : getObjectNames(mbs)) {
 369             result.add(ManagementFactory.
 370                 newPlatformMXBeanProxy(mbs,
 371                                        on.getCanonicalName(),
 372                                        mxbeanInterface)
 373             );
 374         }
 375         return result;
 376     }
 377 
 378     private Set<ObjectName> getObjectNames(MBeanServerConnection mbs)
 379         throws java.io.IOException
 380     {
 381         String domainAndType = domain + ":type=" + type;
 382         if (keyProperties.size() > 1) {
 383             // if there are more than 1 key properties (i.e. other than "type")
 384             domainAndType += ",*";
 385         }
 386         ObjectName on = Util.newObjectName(domainAndType);
 387         Set<ObjectName> set =  mbs.queryNames(on, null);
 388         for (PlatformComponent pc : subComponents) {
 389             set.addAll(pc.getObjectNames(mbs));
 390         }
 391         return set;
 392     }
 393 
 394     private static final long serialVersionUID = 6992337162326171013L;
 395 }