8065213: Specify and implement PlatformMBeanProvider for looking for all platform MBeans
Reviewed-by: dfuchs, mchung, jbachorik
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.management/share/classes/META-INF/services/sun.management.spi.PlatformMBeanProvider Thu Feb 05 12:13:45 2015 +0100
@@ -0,0 +1,25 @@
+#
+# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation. Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+com.sun.management.internal.PlatformMBeanProviderImpl
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.management/share/classes/com/sun/management/internal/PlatformMBeanProviderImpl.java Thu Feb 05 12:13:45 2015 +0100
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.management.internal;
+
+import java.lang.management.ManagementFactory;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import javax.management.DynamicMBean;
+import javax.management.ObjectName;
+import sun.management.ManagementFactoryHelper;
+import sun.management.spi.PlatformMBeanProvider;
+
+public final class PlatformMBeanProviderImpl extends PlatformMBeanProvider {
+ private final List<PlatformComponent<?>> mxbeanList;
+
+ public PlatformMBeanProviderImpl() {
+ mxbeanList = Collections.unmodifiableList(init());
+ }
+
+ @Override
+ public List<PlatformComponent<?>> getPlatformComponentList() {
+ return mxbeanList;
+ }
+
+ private List<PlatformComponent<?>> init() {
+ ArrayList<PlatformComponent<?>> initMBeanList = new ArrayList<>();
+ /**
+ * Garbage Collector in the Java virtual machine.
+ */
+ initMBeanList.add(new PlatformComponent<java.lang.management.MemoryManagerMXBean>() {
+ private final Set<String> garbageCollectorMXBeanInterfaceNames
+ = Collections.unmodifiableSet(
+ Stream.of("java.lang.management.MemoryManagerMXBean",
+ "java.lang.management.GarbageCollectorMXBean",
+ "com.sun.management.GarbageCollectorMXBean")
+ .collect(Collectors.toSet()));
+
+ @Override
+ public Set<Class<? extends java.lang.management.MemoryManagerMXBean>> mbeanInterfaces() {
+ return Stream.of(java.lang.management.MemoryManagerMXBean.class,
+ java.lang.management.GarbageCollectorMXBean.class,
+ com.sun.management.GarbageCollectorMXBean.class)
+ .collect(Collectors.toSet());
+ }
+
+ @Override
+ public Set<String> mbeanInterfaceNames() {
+ return garbageCollectorMXBeanInterfaceNames;
+ }
+
+ @Override
+ public String getObjectNamePattern() {
+ return ManagementFactory.GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE + ",name=*";
+ }
+
+ @Override
+ public boolean isSingleton() {
+ return false; // zero or more instances
+ }
+
+ @Override
+ public Map<String, java.lang.management.MemoryManagerMXBean> nameToMBeanMap() {
+ List<java.lang.management.GarbageCollectorMXBean> list
+ = ManagementFactoryHelper.getGarbageCollectorMXBeans();;
+ Map<String, java.lang.management.MemoryManagerMXBean> map;
+ if (list.isEmpty()) {
+ map = Collections.<String, java.lang.management.MemoryManagerMXBean>emptyMap();
+ } else {
+ map = new HashMap<>(list.size());
+ for (java.lang.management.MemoryManagerMXBean gcm : list) {
+ map.put(gcm.getObjectName().getCanonicalName(),
+ gcm);
+ }
+ }
+ return map;
+ }
+ });
+
+ /**
+ * OperatingSystemMXBean
+ */
+ initMBeanList.add(new PlatformComponent<java.lang.management.OperatingSystemMXBean>() {
+ private final Set<String> operatingSystemMXBeanInterfaceNames
+ = Collections.unmodifiableSet(
+ Stream.of("java.lang.management.OperatingSystemMXBean",
+ "com.sun.management.OperatingSystemMXBean",
+ "com.sun.management.UnixOperatingSystemMXBean")
+ .collect(Collectors.toSet()));
+
+ @Override
+ public Set<Class<? extends java.lang.management.OperatingSystemMXBean>> mbeanInterfaces() {
+ return Stream.of(java.lang.management.OperatingSystemMXBean.class,
+ com.sun.management.OperatingSystemMXBean.class,
+ com.sun.management.UnixOperatingSystemMXBean.class)
+ .collect(Collectors.toSet());
+ }
+
+ @Override
+ public Set<String> mbeanInterfaceNames() {
+ return operatingSystemMXBeanInterfaceNames;
+ }
+
+ @Override
+ public String getObjectNamePattern() {
+ return ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME;
+ }
+
+ @Override
+ public Map<String, java.lang.management.OperatingSystemMXBean> nameToMBeanMap() {
+ return Collections.<String, java.lang.management.OperatingSystemMXBean>singletonMap(
+ ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME,
+ ManagementFactoryHelper.getOperatingSystemMXBean());
+ }
+ });
+
+ /**
+ * Diagnostic support for the HotSpot Virtual Machine.
+ */
+ initMBeanList.add(new PlatformComponent<com.sun.management.HotSpotDiagnosticMXBean>() {
+ private final Set<String> hotSpotDiagnosticMXBeanInterfaceNames =
+ Collections.unmodifiableSet(Collections.<String>singleton("com.sun.management.HotSpotDiagnosticMXBean"));
+
+ @Override
+ public Set<Class<? extends com.sun.management.HotSpotDiagnosticMXBean>> mbeanInterfaces() {
+ return Collections.singleton(com.sun.management.HotSpotDiagnosticMXBean.class);
+ }
+
+ @Override
+ public Set<String> mbeanInterfaceNames() {
+ return hotSpotDiagnosticMXBeanInterfaceNames;
+ }
+
+ @Override
+ public String getObjectNamePattern() {
+ return "com.sun.management:type=HotSpotDiagnostic";
+ }
+
+ @Override
+ public Map<String, com.sun.management.HotSpotDiagnosticMXBean> nameToMBeanMap() {
+ return Collections.<String, com.sun.management.HotSpotDiagnosticMXBean>singletonMap(
+ "com.sun.management:type=HotSpotDiagnostic",
+ ManagementFactoryHelper.getDiagnosticMXBean());
+ }
+ });
+
+ /**
+ * DynamicMBean
+ */
+ HashMap<ObjectName, DynamicMBean> dynmbeans
+ = ManagementFactoryHelper.getPlatformDynamicMBeans();
+ final Set<String> dynamicMBeanInterfaceNames =
+ Collections.unmodifiableSet(Collections.<String>singleton("javax.management.DynamicMBean"));
+ for (Map.Entry<ObjectName, DynamicMBean> e : dynmbeans.entrySet()) {
+ initMBeanList.add(new PlatformComponent<DynamicMBean>() {
+ @Override
+ public Set<String> mbeanInterfaceNames() {
+ return dynamicMBeanInterfaceNames;
+ }
+
+ @Override
+ public Set<Class<? extends DynamicMBean>> mbeanInterfaces() {
+ return Collections.emptySet(); // DynamicMBean cannot be used to find an MBean by ManagementFactory
+ }
+
+ @Override
+ public String getObjectNamePattern() {
+ return e.getKey().getCanonicalName();
+ }
+
+ @Override
+ public Map<String, DynamicMBean> nameToMBeanMap() {
+ return Collections.<String, DynamicMBean>singletonMap(
+ e.getKey().getCanonicalName(),
+ e.getValue());
+ }
+ });
+ }
+ initMBeanList.trimToSize();
+ return initMBeanList;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.management/share/classes/java/lang/management/DefaultPlatformMBeanProvider.java Thu Feb 05 12:13:45 2015 +0100
@@ -0,0 +1,503 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.lang.management;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import javax.management.DynamicMBean;
+import javax.management.ObjectName;
+import sun.management.ManagementFactoryHelper;
+import sun.management.spi.PlatformMBeanProvider;
+
+class DefaultPlatformMBeanProvider extends PlatformMBeanProvider {
+ private final List<PlatformComponent<?>> mxbeanList;
+
+ DefaultPlatformMBeanProvider() {
+ mxbeanList = Collections.unmodifiableList(init());
+ }
+
+ @Override
+ public List<PlatformComponent<?>> getPlatformComponentList() {
+ return mxbeanList;
+ }
+
+ private List<PlatformComponent<?>> init() {
+ ArrayList<PlatformComponent<?>> initMBeanList = new ArrayList<>();
+ /**
+ * Class loading system of the Java virtual machine.
+ */
+ initMBeanList.add(new PlatformComponent<ClassLoadingMXBean>() {
+ private final Set<String> classLoadingInterfaceNames =
+ Collections.unmodifiableSet(Collections.singleton(
+ "java.lang.management.ClassLoadingMXBean"));
+
+ @Override
+ public Set<Class<? extends ClassLoadingMXBean>> mbeanInterfaces() {
+ return Collections.singleton(ClassLoadingMXBean.class);
+ }
+
+ @Override
+ public Set<String> mbeanInterfaceNames() {
+ return classLoadingInterfaceNames;
+ }
+
+ @Override
+ public String getObjectNamePattern() {
+ return ManagementFactory.CLASS_LOADING_MXBEAN_NAME;
+ }
+
+ @Override
+ public Map<String, ClassLoadingMXBean> nameToMBeanMap() {
+ return Collections.singletonMap(
+ ManagementFactory.CLASS_LOADING_MXBEAN_NAME,
+ ManagementFactoryHelper.getClassLoadingMXBean());
+ }
+ });
+
+ /**
+ * Compilation system of the Java virtual machine.
+ */
+ initMBeanList.add(new PlatformComponent<CompilationMXBean>() {
+ private final Set<String> compilationMXBeanInterfaceNames
+ = Collections.unmodifiableSet(Collections.singleton(
+ "java.lang.management.CompilationMXBean"));
+
+ @Override
+ public Set<Class<? extends CompilationMXBean>> mbeanInterfaces() {
+ return Collections.singleton(CompilationMXBean.class);
+ }
+
+ @Override
+ public Set<String> mbeanInterfaceNames() {
+ return compilationMXBeanInterfaceNames;
+ }
+
+ @Override
+ public String getObjectNamePattern() {
+ return ManagementFactory.COMPILATION_MXBEAN_NAME;
+ }
+
+ @Override
+ public Map<String, CompilationMXBean> nameToMBeanMap() {
+ CompilationMXBean m = ManagementFactoryHelper.getCompilationMXBean();
+ if (m == null) {
+ return Collections.emptyMap();
+ } else {
+ return Collections.singletonMap(
+ ManagementFactory.COMPILATION_MXBEAN_NAME,
+ ManagementFactoryHelper.getCompilationMXBean());
+ }
+ }
+ });
+
+ /**
+ * Memory system of the Java virtual machine.
+ */
+ initMBeanList.add(new PlatformComponent<MemoryMXBean>() {
+ private final Set<String> memoryMXBeanInterfaceNames
+ = Collections.unmodifiableSet(Collections.singleton(
+ "java.lang.management.MemoryMXBean"));
+
+ @Override
+ public Set<Class<? extends MemoryMXBean>> mbeanInterfaces() {
+ return Collections.singleton(MemoryMXBean.class);
+ }
+
+ @Override
+ public Set<String> mbeanInterfaceNames() {
+ return memoryMXBeanInterfaceNames;
+ }
+
+ @Override
+ public String getObjectNamePattern() {
+ return ManagementFactory.MEMORY_MXBEAN_NAME;
+ }
+
+ @Override
+ public Map<String, MemoryMXBean> nameToMBeanMap() {
+ return Collections.singletonMap(
+ ManagementFactory.MEMORY_MXBEAN_NAME,
+ ManagementFactoryHelper.getMemoryMXBean());
+ }
+ });
+
+ /**
+ * Garbage Collector in the Java virtual machine.
+ */
+ initMBeanList.add(new PlatformComponent<MemoryManagerMXBean>() {
+ private final Set<String> garbageCollectorMXBeanInterfaceNames
+ = Collections.unmodifiableSet(
+ Stream.of("java.lang.management.MemoryManagerMXBean",
+ "java.lang.management.GarbageCollectorMXBean")
+ .collect(Collectors.toSet()));
+ @Override
+ public Set<Class<? extends MemoryManagerMXBean>> mbeanInterfaces() {
+ return Stream.of(MemoryManagerMXBean.class,
+ GarbageCollectorMXBean.class,
+ com.sun.management.GarbageCollectorMXBean.class).collect(Collectors.toSet());
+ }
+
+ @Override
+ public Set<String> mbeanInterfaceNames() {
+ return garbageCollectorMXBeanInterfaceNames;
+ }
+
+ @Override
+ public String getObjectNamePattern() {
+ return ManagementFactory.GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE + ",name=*";
+ }
+
+ @Override
+ public boolean isSingleton() {
+ return false; // zero or more instances
+ }
+
+ @Override
+ public Map<String, MemoryManagerMXBean> nameToMBeanMap() {
+ List<GarbageCollectorMXBean> list
+ = ManagementFactoryHelper.getGarbageCollectorMXBeans();
+ Map<String, MemoryManagerMXBean> map;
+ if (list.isEmpty()) {
+ map = Collections.emptyMap();
+ } else {
+ map = new HashMap<>(list.size());
+ for (MemoryManagerMXBean gcm : list) {
+ map.put(gcm.getObjectName().getCanonicalName(),
+ gcm);
+ }
+ }
+ return map;
+ }
+
+ });
+
+ /**
+ * Memory manager in the Java virtual machine.
+ */
+ initMBeanList.add(new PlatformComponent<MemoryManagerMXBean>() {
+ private final Set<String> memoryManagerMXBeanInterfaceNames
+ = Collections.unmodifiableSet(Collections.singleton(
+ "java.lang.management.MemoryManagerMXBean"));
+
+ @Override
+ public Set<Class<? extends MemoryManagerMXBean>> mbeanInterfaces() {
+ return Collections.singleton(MemoryManagerMXBean.class);
+ }
+
+ @Override
+ public Set<String> mbeanInterfaceNames() {
+ return memoryManagerMXBeanInterfaceNames;
+ }
+
+ @Override
+ public String getObjectNamePattern() {
+ return ManagementFactory.MEMORY_MANAGER_MXBEAN_DOMAIN_TYPE + ",name=*";
+ }
+
+ @Override
+ public boolean isSingleton() {
+ return false; // zero or more instances
+ }
+
+ @Override
+ public Map<String, MemoryManagerMXBean> nameToMBeanMap() {
+ List<MemoryManagerMXBean> list
+ = ManagementFactoryHelper.getMemoryManagerMXBeans();
+ return list.stream()
+ .filter(this::isMemoryManager)
+ .collect(Collectors.toMap(
+ pmo -> pmo.getObjectName().getCanonicalName(), Function.identity()));
+ }
+
+ // ManagementFactoryHelper.getMemoryManagerMXBeans() returns all
+ // memory managers - we need to filter out those that do not match
+ // the pattern for which we are registered
+ private boolean isMemoryManager(MemoryManagerMXBean mbean) {
+ final ObjectName name = mbean.getObjectName();
+ return ManagementFactory.MEMORY_MANAGER_MXBEAN_DOMAIN_TYPE.startsWith(name.getDomain())
+ && ManagementFactory.MEMORY_MANAGER_MXBEAN_DOMAIN_TYPE.contains(
+ "type="+name.getKeyProperty("type"));
+ }
+ });
+
+ /**
+ * Memory pool in the Java virtual machine.
+ */
+ initMBeanList.add(new PlatformComponent<MemoryPoolMXBean>() {
+ private final Set<String> memoryPoolMXBeanInterfaceNames
+ = Collections.unmodifiableSet(Collections.singleton(
+ "java.lang.management.MemoryPoolMXBean"));
+
+ @Override
+ public Set<Class<? extends MemoryPoolMXBean>> mbeanInterfaces() {
+ return Collections.singleton(MemoryPoolMXBean.class);
+ }
+
+ @Override
+ public Set<String> mbeanInterfaceNames() {
+ return memoryPoolMXBeanInterfaceNames;
+ }
+
+ @Override
+ public String getObjectNamePattern() {
+ return ManagementFactory.MEMORY_POOL_MXBEAN_DOMAIN_TYPE + ",name=*";
+ }
+
+ @Override
+ public boolean isSingleton() {
+ return false; // zero or more instances
+ }
+
+ @Override
+ public Map<String, MemoryPoolMXBean> nameToMBeanMap() {
+ List<MemoryPoolMXBean> list
+ = ManagementFactoryHelper.getMemoryPoolMXBeans();
+ Map<String, MemoryPoolMXBean> map;
+ if (list.isEmpty()) {
+ map = Collections.<String, MemoryPoolMXBean>emptyMap();
+ } else {
+ map = new HashMap<>(list.size());
+ for (MemoryPoolMXBean mpm : list) {
+ map.put(mpm.getObjectName().getCanonicalName(),
+ mpm);
+ }
+ }
+ return map;
+ }
+ });
+
+ /**
+ * Runtime system of the Java virtual machine.
+ */
+ initMBeanList.add(new PlatformComponent<RuntimeMXBean>() {
+ private final Set<String> runtimeMXBeanInterfaceNames
+ = Collections.unmodifiableSet(Collections.singleton(
+ "java.lang.management.RuntimeMXBean"));
+
+ @Override
+ public Set<Class<? extends RuntimeMXBean>> mbeanInterfaces() {
+ return Collections.singleton(RuntimeMXBean.class);
+ }
+
+ @Override
+ public Set<String> mbeanInterfaceNames() {
+ return runtimeMXBeanInterfaceNames;
+ }
+
+ @Override
+ public String getObjectNamePattern() {
+ return ManagementFactory.RUNTIME_MXBEAN_NAME;
+ }
+
+ @Override
+ public Map<String, RuntimeMXBean> nameToMBeanMap() {
+ return Collections.singletonMap(
+ ManagementFactory.RUNTIME_MXBEAN_NAME,
+ ManagementFactoryHelper.getRuntimeMXBean());
+ }
+ });
+
+ /**
+ * Threading system of the Java virtual machine.
+ */
+ initMBeanList.add(new PlatformComponent<ThreadMXBean>() {
+ private final Set<String> threadMXBeanInterfaceNames
+ = Collections.unmodifiableSet(Collections.singleton(
+ "java.lang.management.ThreadMXBean"));
+
+ @Override
+ public Set<Class<? extends ThreadMXBean>> mbeanInterfaces() {
+ return Collections.singleton(ThreadMXBean.class);
+ }
+
+ @Override
+ public Set<String> mbeanInterfaceNames() {
+ return threadMXBeanInterfaceNames;
+ }
+
+ @Override
+ public String getObjectNamePattern() {
+ return ManagementFactory.THREAD_MXBEAN_NAME;
+ }
+
+ @Override
+ public Map<String, ThreadMXBean> nameToMBeanMap() {
+ return Collections.singletonMap(
+ ManagementFactory.THREAD_MXBEAN_NAME,
+ ManagementFactoryHelper.getThreadMXBean());
+ }
+ });
+
+ /**
+ * Logging facility.
+ */
+ initMBeanList.add(new PlatformComponent<PlatformLoggingMXBean>() {
+ private final Set<String> platformLoggingMXBeanInterfaceNames
+ = Collections.unmodifiableSet(Collections.singleton(
+ "java.lang.management.PlatformLoggingMXBean"));
+
+ @Override
+ public Set<Class<? extends PlatformLoggingMXBean>> mbeanInterfaces() {
+ return Collections.singleton(PlatformLoggingMXBean.class);
+ }
+
+ @Override
+ public Set<String> mbeanInterfaceNames() {
+ return platformLoggingMXBeanInterfaceNames;
+ }
+
+ @Override
+ public String getObjectNamePattern() {
+ return "java.util.logging:type=Logging";
+ }
+
+ @Override
+ public Map<String, PlatformLoggingMXBean> nameToMBeanMap() {
+ return Collections.singletonMap(
+ "java.util.logging:type=Logging",
+ ManagementFactoryHelper.getPlatformLoggingMXBean());
+ }
+ });
+
+ /**
+ * Buffer pools.
+ */
+ initMBeanList.add(new PlatformComponent<BufferPoolMXBean>() {
+ private final Set<String> bufferPoolMXBeanInterfaceNames
+ = Collections.unmodifiableSet(Collections.singleton(
+ "java.lang.management.BufferPoolMXBean"));
+
+ @Override
+ public Set<Class<? extends BufferPoolMXBean>> mbeanInterfaces() {
+ return Collections.singleton(BufferPoolMXBean.class);
+ }
+
+ @Override
+ public Set<String> mbeanInterfaceNames() {
+ return bufferPoolMXBeanInterfaceNames;
+ }
+
+ @Override
+ public String getObjectNamePattern() {
+ return "java.nio:type=BufferPool,name=*";
+ }
+
+ @Override
+ public boolean isSingleton() {
+ return false; // zero or more instances
+ }
+
+ @Override
+ public Map<String, BufferPoolMXBean> nameToMBeanMap() {
+ List<BufferPoolMXBean> list
+ = ManagementFactoryHelper.getBufferPoolMXBeans();
+ Map<String, BufferPoolMXBean> map;
+ if (list.isEmpty()) {
+ map = Collections.<String, BufferPoolMXBean>emptyMap();
+ } else {
+ map = new HashMap<>(list.size());
+ list.stream()
+ .forEach(mbean -> map.put(mbean.getObjectName().getCanonicalName(),mbean));
+ }
+ return map;
+ }
+ });
+
+ /**
+ * OperatingSystemMXBean
+ */
+ initMBeanList.add(new PlatformComponent<OperatingSystemMXBean>() {
+ private final Set<String> operatingSystemMXBeanInterfaceNames
+ = Collections.unmodifiableSet(Collections.singleton(
+ "java.lang.management.OperatingSystemMXBean"));
+
+ @Override
+ public Set<Class<? extends OperatingSystemMXBean>> mbeanInterfaces() {
+ return Collections.singleton(OperatingSystemMXBean.class);
+ }
+
+ @Override
+ public Set<String> mbeanInterfaceNames() {
+ return operatingSystemMXBeanInterfaceNames;
+ }
+
+ @Override
+ public String getObjectNamePattern() {
+ return ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME;
+ }
+
+ @Override
+ public Map<String, OperatingSystemMXBean> nameToMBeanMap() {
+ return Collections.singletonMap(
+ ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME,
+ ManagementFactoryHelper.getOperatingSystemMXBean());
+ }
+
+ });
+
+ /**
+ * DynamicMBean
+ */
+ HashMap<ObjectName, DynamicMBean> dynmbeans
+ = ManagementFactoryHelper.getPlatformDynamicMBeans();
+ final Set<String> dynamicMBeanInterfaceNames =
+ Collections.unmodifiableSet(Collections.singleton("javax.management.DynamicMBean"));
+ for (Map.Entry<ObjectName, DynamicMBean> e : dynmbeans.entrySet()) {
+ initMBeanList.add(new PlatformComponent<DynamicMBean>() {
+ @Override
+ public Set<Class<? extends DynamicMBean>> mbeanInterfaces() {
+ return Collections.emptySet();
+ }
+
+ @Override
+ public Set<String> mbeanInterfaceNames() {
+ return dynamicMBeanInterfaceNames;
+ }
+
+ @Override
+ public String getObjectNamePattern() {
+ return e.getKey().getCanonicalName();
+ }
+
+ @Override
+ public Map<String, DynamicMBean> nameToMBeanMap() {
+ return Collections.<String, DynamicMBean>singletonMap(
+ e.getKey().getCanonicalName(),
+ e.getValue());
+ }
+ });
+ }
+
+ initMBeanList.trimToSize();
+ return initMBeanList;
+ }
+}
--- a/jdk/src/java.management/share/classes/java/lang/management/ManagementFactory.java Thu Feb 05 11:42:39 2015 +0800
+++ b/jdk/src/java.management/share/classes/java/lang/management/ManagementFactory.java Thu Feb 05 12:13:45 2015 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,35 +24,40 @@
*/
package java.lang.management;
+import java.io.FilePermission;
+import java.io.IOException;
import javax.management.DynamicMBean;
import javax.management.MBeanServer;
import javax.management.MBeanServerConnection;
import javax.management.MBeanServerFactory;
import javax.management.MBeanServerPermission;
import javax.management.NotificationEmitter;
-import javax.management.ObjectInstance;
import javax.management.ObjectName;
-import javax.management.InstanceAlreadyExistsException;
import javax.management.InstanceNotFoundException;
import javax.management.MalformedObjectNameException;
-import javax.management.MBeanRegistrationException;
-import javax.management.NotCompliantMBeanException;
import javax.management.StandardEmitterMBean;
import javax.management.StandardMBean;
import java.util.Collections;
import java.util.List;
import java.util.Set;
-import java.util.HashMap;
-import java.util.HashSet;
import java.util.Map;
import java.security.AccessController;
import java.security.Permission;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Optional;
+import java.util.ServiceLoader;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import static java.util.stream.Collectors.toMap;
+import java.util.stream.Stream;
import javax.management.JMX;
-import sun.management.ManagementFactoryHelper;
-import sun.management.ExtendedPlatformComponent;
+import sun.management.Util;
+import sun.management.spi.PlatformMBeanProvider;
+import sun.management.spi.PlatformMBeanProvider.PlatformComponent;
/**
* The {@code ManagementFactory} class is a factory class for getting
@@ -316,7 +321,7 @@
* the Java virtual machine.
*/
public static ClassLoadingMXBean getClassLoadingMXBean() {
- return ManagementFactoryHelper.getClassLoadingMXBean();
+ return getPlatformMXBean(ClassLoadingMXBean.class);
}
/**
@@ -326,7 +331,7 @@
* @return a {@link MemoryMXBean} object for the Java virtual machine.
*/
public static MemoryMXBean getMemoryMXBean() {
- return ManagementFactoryHelper.getMemoryMXBean();
+ return getPlatformMXBean(MemoryMXBean.class);
}
/**
@@ -336,7 +341,7 @@
* @return a {@link ThreadMXBean} object for the Java virtual machine.
*/
public static ThreadMXBean getThreadMXBean() {
- return ManagementFactoryHelper.getThreadMXBean();
+ return getPlatformMXBean(ThreadMXBean.class);
}
/**
@@ -347,7 +352,7 @@
*/
public static RuntimeMXBean getRuntimeMXBean() {
- return ManagementFactoryHelper.getRuntimeMXBean();
+ return getPlatformMXBean(RuntimeMXBean.class);
}
/**
@@ -360,7 +365,7 @@
* no compilation system.
*/
public static CompilationMXBean getCompilationMXBean() {
- return ManagementFactoryHelper.getCompilationMXBean();
+ return getPlatformMXBean(CompilationMXBean.class);
}
/**
@@ -371,7 +376,7 @@
* the Java virtual machine.
*/
public static OperatingSystemMXBean getOperatingSystemMXBean() {
- return ManagementFactoryHelper.getOperatingSystemMXBean();
+ return getPlatformMXBean(OperatingSystemMXBean.class);
}
/**
@@ -384,7 +389,7 @@
*
*/
public static List<MemoryPoolMXBean> getMemoryPoolMXBeans() {
- return ManagementFactoryHelper.getMemoryPoolMXBeans();
+ return getPlatformMXBeans(MemoryPoolMXBean.class);
}
/**
@@ -397,7 +402,7 @@
*
*/
public static List<MemoryManagerMXBean> getMemoryManagerMXBeans() {
- return ManagementFactoryHelper.getMemoryManagerMXBeans();
+ return getPlatformMXBeans(MemoryManagerMXBean.class);
}
@@ -413,7 +418,7 @@
*
*/
public static List<GarbageCollectorMXBean> getGarbageCollectorMXBeans() {
- return ManagementFactoryHelper.getGarbageCollectorMXBeans();
+ return getPlatformMXBeans(GarbageCollectorMXBean.class);
}
private static MBeanServer platformMBeanServer;
@@ -467,35 +472,11 @@
if (platformMBeanServer == null) {
platformMBeanServer = MBeanServerFactory.createMBeanServer();
- for (PlatformComponent pc : PlatformComponent.values()) {
- List<? extends PlatformManagedObject> list =
- pc.getMXBeans(pc.getMXBeanInterface());
- for (PlatformManagedObject o : list) {
- // Each PlatformComponent represents one management
- // interface. Some MXBean may extend another one.
- // The MXBean instances for one platform component
- // (returned by pc.getMXBeans()) might be also
- // the MXBean instances for another platform component.
- // e.g. com.sun.management.GarbageCollectorMXBean
- //
- // So need to check if an MXBean instance is registered
- // before registering into the platform MBeanServer
- if (!platformMBeanServer.isRegistered(o.getObjectName())) {
- addMXBean(platformMBeanServer, o);
- }
- }
- }
- HashMap<ObjectName, DynamicMBean> dynmbeans =
- ManagementFactoryHelper.getPlatformDynamicMBeans();
- for (Map.Entry<ObjectName, DynamicMBean> e : dynmbeans.entrySet()) {
- addDynamicMBean(platformMBeanServer, e.getValue(), e.getKey());
- }
- for (final PlatformManagedObject o :
- ExtendedPlatformComponent.getMXBeans()) {
- if (!platformMBeanServer.isRegistered(o.getObjectName())) {
- addMXBean(platformMBeanServer, o);
- }
- }
+ platformComponents()
+ .stream()
+ .filter(PlatformComponent::shouldRegister)
+ .flatMap(pc -> pc.nameToMBeanMap().entrySet().stream())
+ .forEach(entry -> addMXBean(platformMBeanServer, entry.getKey(), entry.getValue()));
}
return platformMBeanServer;
}
@@ -600,11 +581,8 @@
// bootstrap class loader
final Class<?> cls = mxbeanInterface;
ClassLoader loader =
- AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
- public ClassLoader run() {
- return cls.getClassLoader();
- }
- });
+ AccessController.doPrivileged(
+ (PrivilegedAction<ClassLoader>) () -> cls.getClassLoader());
if (!sun.misc.VM.isSystemDomainLoader(loader)) {
throw new IllegalArgumentException(mxbeanName +
" is not a platform MXBean");
@@ -619,7 +597,6 @@
" is not an instance of " + mxbeanInterface);
}
- final Class<?>[] interfaces;
// check if the registered MBean is a notification emitter
boolean emitter = connection.isInstanceOf(objName, NOTIF_EMITTER);
@@ -661,20 +638,11 @@
*/
public static <T extends PlatformManagedObject>
T getPlatformMXBean(Class<T> mxbeanInterface) {
- PlatformComponent pc = PlatformComponent.getPlatformComponent(mxbeanInterface);
- if (pc == null) {
- T mbean = ExtendedPlatformComponent.getMXBean(mxbeanInterface);
- if (mbean != null) {
- return mbean;
- }
- throw new IllegalArgumentException(mxbeanInterface.getName() +
- " is not a platform management interface");
- }
- if (!pc.isSingleton())
- throw new IllegalArgumentException(mxbeanInterface.getName() +
- " can have zero or more than one instances");
+ PlatformComponent<?> pc = PlatformMBeanFinder.findSingleton(mxbeanInterface);
- return pc.getSingletonMXBean(mxbeanInterface);
+ List<? extends T> mbeans = pc.getMBeans(mxbeanInterface);
+ assert mbeans.isEmpty() || mbeans.size() == 1;
+ return mbeans.isEmpty() ? null : mbeans.get(0);
}
/**
@@ -701,16 +669,19 @@
*/
public static <T extends PlatformManagedObject> List<T>
getPlatformMXBeans(Class<T> mxbeanInterface) {
- PlatformComponent pc = PlatformComponent.getPlatformComponent(mxbeanInterface);
+ // Validates at first the specified interface by finding at least one
+ // PlatformComponent whose MXBean implements this interface.
+ // An interface can be implemented by different MBeans, provided by
+ // different platform components.
+ PlatformComponent<?> pc = PlatformMBeanFinder.findFirst(mxbeanInterface);
if (pc == null) {
- T mbean = ExtendedPlatformComponent.getMXBean(mxbeanInterface);
- if (mbean != null) {
- return Collections.singletonList(mbean);
- }
- throw new IllegalArgumentException(mxbeanInterface.getName() +
- " is not a platform management interface");
+ throw new IllegalArgumentException(mxbeanInterface.getName()
+ + " is not a platform management interface");
}
- return Collections.unmodifiableList(pc.getMXBeans(mxbeanInterface));
+
+ return platformComponents().stream()
+ .flatMap(p -> p.getMBeans(mxbeanInterface).stream())
+ .collect(Collectors.toList());
}
/**
@@ -753,22 +724,8 @@
Class<T> mxbeanInterface)
throws java.io.IOException
{
- PlatformComponent pc = PlatformComponent.getPlatformComponent(mxbeanInterface);
- if (pc == null) {
- T mbean = ExtendedPlatformComponent.getMXBean(mxbeanInterface);
- if (mbean != null) {
- ObjectName on = mbean.getObjectName();
- return ManagementFactory.newPlatformMXBeanProxy(connection,
- on.getCanonicalName(),
- mxbeanInterface);
- }
- throw new IllegalArgumentException(mxbeanInterface.getName() +
- " is not a platform management interface");
- }
- if (!pc.isSingleton())
- throw new IllegalArgumentException(mxbeanInterface.getName() +
- " can have zero or more than one instances");
- return pc.getSingletonMXBean(connection, mxbeanInterface);
+ PlatformComponent<?> pc = PlatformMBeanFinder.findSingleton(mxbeanInterface);
+ return newPlatformMXBeanProxy(connection, pc.getObjectNamePattern(), mxbeanInterface);
}
/**
@@ -804,19 +761,56 @@
Class<T> mxbeanInterface)
throws java.io.IOException
{
- PlatformComponent pc = PlatformComponent.getPlatformComponent(mxbeanInterface);
+ // Validates at first the specified interface by finding at least one
+ // PlatformComponent whose MXBean implements this interface.
+ // An interface can be implemented by different MBeans, provided by
+ // different platform components.
+ PlatformComponent<?> pc = PlatformMBeanFinder.findFirst(mxbeanInterface);
if (pc == null) {
- T mbean = ExtendedPlatformComponent.getMXBean(mxbeanInterface);
- if (mbean != null) {
- ObjectName on = mbean.getObjectName();
- T proxy = ManagementFactory.newPlatformMXBeanProxy(connection,
- on.getCanonicalName(), mxbeanInterface);
- return Collections.singletonList(proxy);
+ throw new IllegalArgumentException(mxbeanInterface.getName()
+ + " is not a platform management interface");
+ }
+
+ // Collect all names, eliminate duplicates.
+ Stream<String> names = Stream.empty();
+ for (PlatformComponent<?> p : platformComponents()) {
+ names = Stream.concat(names, getProxyNames(p, connection, mxbeanInterface));
+ }
+ Set<String> objectNames = names.collect(Collectors.toSet());
+ if (objectNames.isEmpty()) return Collections.emptyList();
+
+ // Map names on proxies.
+ List<T> proxies = new ArrayList<>();
+ for (String name : objectNames) {
+ proxies.add(newPlatformMXBeanProxy(connection, name, mxbeanInterface));
+ }
+ return proxies;
+ }
+
+ // Returns a stream containing all ObjectNames of the MBeans represented by
+ // the specified PlatformComponent and implementing the specified interface.
+ // If the PlatformComponent is a singleton, the name returned by
+ // PlatformComponent.getObjectNamePattern() will be used, otherwise
+ // we will query the specified MBeanServerConnection (conn.queryNames)
+ // with the pattern returned by PlatformComponent.getObjectNamePattern()
+ // in order to find the names of matching MBeans.
+ // In case of singleton, we do not check whether the MBean is registered
+ // in the connection because the caller "getPlatformMXBeans" will do the check
+ // when creating a proxy.
+ private static Stream<String> getProxyNames(PlatformComponent<?> pc,
+ MBeanServerConnection conn,
+ Class<?> intf)
+ throws IOException
+ {
+ if (pc.mbeanInterfaceNames().contains(intf.getName())) {
+ if (pc.isSingleton()) {
+ return Stream.of(pc.getObjectNamePattern());
+ } else {
+ return conn.queryNames(Util.newObjectName(pc.getObjectNamePattern()), null)
+ .stream().map(ObjectName::getCanonicalName);
}
- throw new IllegalArgumentException(mxbeanInterface.getName() +
- " is not a platform management interface");
}
- return Collections.unmodifiableList(pc.getMXBeans(connection, mxbeanInterface));
+ return Stream.empty();
}
/**
@@ -835,63 +829,145 @@
public static Set<Class<? extends PlatformManagedObject>>
getPlatformManagementInterfaces()
{
- Set<Class<? extends PlatformManagedObject>> result =
- new HashSet<>();
- for (PlatformComponent component: PlatformComponent.values()) {
- result.add(component.getMXBeanInterface());
- }
- return Collections.unmodifiableSet(result);
+ return platformComponents()
+ .stream()
+ .flatMap(pc -> pc.mbeanInterfaces().stream())
+ .filter(clazz -> PlatformManagedObject.class.isAssignableFrom(clazz))
+ .map(clazz -> clazz.asSubclass(PlatformManagedObject.class))
+ .collect(Collectors.toSet());
}
private static final String NOTIF_EMITTER =
"javax.management.NotificationEmitter";
- /**
- * Registers an MXBean.
- */
- private static void addMXBean(final MBeanServer mbs, final PlatformManagedObject pmo) {
- // Make DynamicMBean out of MXBean by wrapping it with a StandardMBean
+ private static void addMXBean(final MBeanServer mbs, String name, final Object pmo)
+ {
try {
- AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
- public Void run() throws InstanceAlreadyExistsException,
- MBeanRegistrationException,
- NotCompliantMBeanException {
- final DynamicMBean dmbean;
- if (pmo instanceof DynamicMBean) {
- dmbean = DynamicMBean.class.cast(pmo);
- } else if (pmo instanceof NotificationEmitter) {
- dmbean = new StandardEmitterMBean(pmo, null, true, (NotificationEmitter) pmo);
- } else {
- dmbean = new StandardMBean(pmo, null, true);
- }
+ ObjectName oname = ObjectName.getInstance(name);
+ // Make DynamicMBean out of MXBean by wrapping it with a StandardMBean
+ AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
+ final DynamicMBean dmbean;
+ if (pmo instanceof DynamicMBean) {
+ dmbean = DynamicMBean.class.cast(pmo);
+ } else if (pmo instanceof NotificationEmitter) {
+ dmbean = new StandardEmitterMBean(pmo, null, true, (NotificationEmitter) pmo);
+ } else {
+ dmbean = new StandardMBean(pmo, null, true);
+ }
- mbs.registerMBean(dmbean, pmo.getObjectName());
- return null;
- }
+ mbs.registerMBean(dmbean, oname);
+ return null;
});
+ } catch (MalformedObjectNameException mone) {
+ throw new IllegalArgumentException(mone);
} catch (PrivilegedActionException e) {
throw new RuntimeException(e.getException());
}
}
- /**
- * Registers a DynamicMBean.
- */
- private static void addDynamicMBean(final MBeanServer mbs,
- final DynamicMBean dmbean,
- final ObjectName on) {
- try {
- AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
- @Override
- public Void run() throws InstanceAlreadyExistsException,
- MBeanRegistrationException,
- NotCompliantMBeanException {
- mbs.registerMBean(dmbean, on);
- return null;
- }
- });
- } catch (PrivilegedActionException e) {
- throw new RuntimeException(e.getException());
+ private static Collection<PlatformComponent<?>> platformComponents()
+ {
+ return PlatformMBeanFinder.getMap().values();
+ }
+
+ private static class PlatformMBeanFinder
+ {
+ private static final Map<String, PlatformComponent<?>> componentMap;
+ static {
+ // get all providers
+ List<PlatformMBeanProvider> providers = AccessController.doPrivileged(
+ (PrivilegedAction<List<PlatformMBeanProvider>>) () -> {
+ List<PlatformMBeanProvider> all = new ArrayList<>();
+ ServiceLoader.loadInstalled(PlatformMBeanProvider.class)
+ .forEach(all::add);
+ all.add(new DefaultPlatformMBeanProvider());
+ return all;
+ }, null, new FilePermission("<<ALL FILES>>", "read"),
+ new RuntimePermission("sun.management.spi.PlatformMBeanProvider"));
+
+ // load all platform components into a map
+ componentMap = providers.stream()
+ .flatMap(p -> toPlatformComponentStream(p))
+ // The first one wins if multiple PlatformComponents
+ // with same ObjectName pattern,
+ .collect(toMap(PlatformComponent::getObjectNamePattern,
+ Function.identity(),
+ (p1, p2) -> p1));
+ }
+
+ static Map<String, PlatformComponent<?>> getMap() {
+ return componentMap;
+ }
+
+ // Loads all platform components from a provider into a stream
+ // Ensures that two different components are not declared with the same
+ // object name pattern. Throws InternalError if the provider incorrectly
+ // declares two platform components with the same pattern.
+ private static Stream<PlatformComponent<?>>
+ toPlatformComponentStream(PlatformMBeanProvider provider)
+ {
+ return provider.getPlatformComponentList()
+ .stream()
+ .collect(toMap(PlatformComponent::getObjectNamePattern,
+ Function.identity(),
+ (p1, p2) -> {
+ throw new InternalError(
+ p1.getObjectNamePattern() +
+ " has been used as key for " + p1 +
+ ", it cannot be reused for " + p2);
+ }))
+ .values().stream();
+ }
+
+ // Finds the first PlatformComponent whose mbeanInterfaceNames() list
+ // contains the specified class name. An MBean interface can be implemented
+ // by different MBeans, provided by different platform components.
+ // For instance the MemoryManagerMXBean interface is implemented both by
+ // regular memory managers, and garbage collector MXBeans. This method is
+ // mainly used to verify that there is at least one PlatformComponent
+ // which provides an implementation of the desired interface.
+ static PlatformComponent<?> findFirst(Class<?> mbeanIntf)
+ {
+ String name = mbeanIntf.getName();
+ Optional<PlatformComponent<?>> op = getMap().values()
+ .stream()
+ .filter(pc -> pc.mbeanInterfaceNames().contains(name))
+ .findFirst();
+
+ if (op.isPresent()) {
+ return op.get();
+ } else {
+ return null;
+ }
+ }
+
+ // Finds a PlatformComponent whose mbeanInterface name list contains
+ // the specified class name, and make sure that one and only one exists.
+ static PlatformComponent<?> findSingleton(Class<?> mbeanIntf)
+ {
+ String name = mbeanIntf.getName();
+ Optional<PlatformComponent<?>> op = getMap().values()
+ .stream()
+ .filter(pc -> pc.mbeanInterfaceNames().contains(name))
+ .reduce((p1, p2) -> {
+ if (p2 != null) {
+ throw new IllegalArgumentException(mbeanIntf.getName() +
+ " can have more than one instance");
+ } else {
+ return p1;
+ }
+ });
+
+ PlatformComponent<?> singleton = op.isPresent() ? op.get() : null;
+ if (singleton == null) {
+ throw new IllegalArgumentException(mbeanIntf.getName() +
+ " is not a platform management interface");
+ }
+ if (!singleton.isSingleton()) {
+ throw new IllegalArgumentException(mbeanIntf.getName() +
+ " can have more than one instance");
+ }
+ return singleton;
}
}
}
--- a/jdk/src/java.management/share/classes/java/lang/management/PlatformComponent.java Thu Feb 05 11:42:39 2015 +0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,468 +0,0 @@
-/*
- * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.lang.management;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.HashSet;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-import javax.management.MBeanServerConnection;
-import javax.management.ObjectName;
-
-import com.sun.management.HotSpotDiagnosticMXBean;
-import com.sun.management.UnixOperatingSystemMXBean;
-
-import sun.management.ManagementFactoryHelper;
-import sun.management.Util;
-
-/**
- * This enum class defines the list of platform components
- * that provides monitoring and management support.
- * Each enum represents one MXBean interface. A MXBean
- * instance could implement one or more MXBean interfaces.
- *
- * For example, com.sun.management.GarbageCollectorMXBean
- * extends java.lang.management.GarbageCollectorMXBean
- * and there is one set of garbage collection MXBean instances,
- * each of which implements both c.s.m. and j.l.m. interfaces.
- * There are two separate enums GARBAGE_COLLECTOR
- * and SUN_GARBAGE_COLLECTOR so that ManagementFactory.getPlatformMXBeans(Class)
- * will return the list of MXBeans of the specified type.
- *
- * To add a new MXBean interface for the Java platform,
- * add a new enum constant and implement the MXBeanFetcher.
- */
-enum PlatformComponent {
-
- /**
- * Class loading system of the Java virtual machine.
- */
- CLASS_LOADING(
- "java.lang.management.ClassLoadingMXBean",
- "java.lang", "ClassLoading", defaultKeyProperties(),
- true, // singleton
- new MXBeanFetcher<ClassLoadingMXBean>() {
- public List<ClassLoadingMXBean> getMXBeans() {
- return Collections.singletonList(ManagementFactoryHelper.getClassLoadingMXBean());
- }
- }),
-
- /**
- * Compilation system of the Java virtual machine.
- */
- COMPILATION(
- "java.lang.management.CompilationMXBean",
- "java.lang", "Compilation", defaultKeyProperties(),
- true, // singleton
- new MXBeanFetcher<CompilationMXBean>() {
- public List<CompilationMXBean> getMXBeans() {
- CompilationMXBean m = ManagementFactoryHelper.getCompilationMXBean();
- if (m == null) {
- return Collections.emptyList();
- } else {
- return Collections.singletonList(m);
- }
- }
- }),
-
- /**
- * Memory system of the Java virtual machine.
- */
- MEMORY(
- "java.lang.management.MemoryMXBean",
- "java.lang", "Memory", defaultKeyProperties(),
- true, // singleton
- new MXBeanFetcher<MemoryMXBean>() {
- public List<MemoryMXBean> getMXBeans() {
- return Collections.singletonList(ManagementFactoryHelper.getMemoryMXBean());
- }
- }),
-
- /**
- * Garbage Collector in the Java virtual machine.
- */
- GARBAGE_COLLECTOR(
- "java.lang.management.GarbageCollectorMXBean",
- "java.lang", "GarbageCollector", keyProperties("name"),
- false, // zero or more instances
- new MXBeanFetcher<GarbageCollectorMXBean>() {
- public List<GarbageCollectorMXBean> getMXBeans() {
- return ManagementFactoryHelper.
- getGarbageCollectorMXBeans();
- }
- }),
-
- /**
- * Memory manager in the Java virtual machine.
- */
- MEMORY_MANAGER(
- "java.lang.management.MemoryManagerMXBean",
- "java.lang", "MemoryManager", keyProperties("name"),
- false, // zero or more instances
- new MXBeanFetcher<MemoryManagerMXBean>() {
- public List<MemoryManagerMXBean> getMXBeans() {
- return ManagementFactoryHelper.getMemoryManagerMXBeans();
- }
- },
- GARBAGE_COLLECTOR),
-
- /**
- * Memory pool in the Java virtual machine.
- */
- MEMORY_POOL(
- "java.lang.management.MemoryPoolMXBean",
- "java.lang", "MemoryPool", keyProperties("name"),
- false, // zero or more instances
- new MXBeanFetcher<MemoryPoolMXBean>() {
- public List<MemoryPoolMXBean> getMXBeans() {
- return ManagementFactoryHelper.getMemoryPoolMXBeans();
- }
- }),
-
- /**
- * Operating system on which the Java virtual machine is running
- */
- OPERATING_SYSTEM(
- "java.lang.management.OperatingSystemMXBean",
- "java.lang", "OperatingSystem", defaultKeyProperties(),
- true, // singleton
- new MXBeanFetcher<OperatingSystemMXBean>() {
- public List<OperatingSystemMXBean> getMXBeans() {
- return Collections.singletonList(ManagementFactoryHelper.getOperatingSystemMXBean());
- }
- }),
-
- /**
- * Runtime system of the Java virtual machine.
- */
- RUNTIME(
- "java.lang.management.RuntimeMXBean",
- "java.lang", "Runtime", defaultKeyProperties(),
- true, // singleton
- new MXBeanFetcher<RuntimeMXBean>() {
- public List<RuntimeMXBean> getMXBeans() {
- return Collections.singletonList(ManagementFactoryHelper.getRuntimeMXBean());
- }
- }),
-
- /**
- * Threading system of the Java virtual machine.
- */
- THREADING(
- "java.lang.management.ThreadMXBean",
- "java.lang", "Threading", defaultKeyProperties(),
- true, // singleton
- new MXBeanFetcher<ThreadMXBean>() {
- public List<ThreadMXBean> getMXBeans() {
- return Collections.singletonList(ManagementFactoryHelper.getThreadMXBean());
- }
- }),
-
-
- /**
- * Logging facility.
- */
- LOGGING(
- "java.lang.management.PlatformLoggingMXBean",
- "java.util.logging", "Logging", defaultKeyProperties(),
- true, // singleton
- new MXBeanFetcher<PlatformLoggingMXBean>() {
- public List<PlatformLoggingMXBean> getMXBeans() {
- PlatformLoggingMXBean m = ManagementFactoryHelper.getPlatformLoggingMXBean();
- if (m == null) {
- return Collections.emptyList();
- } else {
- return Collections.singletonList(m);
- }
- }
- }),
-
- /**
- * Buffer pools.
- */
- BUFFER_POOL(
- "java.lang.management.BufferPoolMXBean",
- "java.nio", "BufferPool", keyProperties("name"),
- false, // zero or more instances
- new MXBeanFetcher<BufferPoolMXBean>() {
- public List<BufferPoolMXBean> getMXBeans() {
- return ManagementFactoryHelper.getBufferPoolMXBeans();
- }
- }),
-
-
- // Sun Platform Extension
-
- /**
- * Sun extension garbage collector that performs collections in cycles.
- */
- SUN_GARBAGE_COLLECTOR(
- "com.sun.management.GarbageCollectorMXBean",
- "java.lang", "GarbageCollector", keyProperties("name"),
- false, // zero or more instances
- new MXBeanFetcher<com.sun.management.GarbageCollectorMXBean>() {
- public List<com.sun.management.GarbageCollectorMXBean> getMXBeans() {
- return getGcMXBeanList(com.sun.management.GarbageCollectorMXBean.class);
- }
- }),
-
- /**
- * Sun extension operating system on which the Java virtual machine
- * is running.
- */
- SUN_OPERATING_SYSTEM(
- "com.sun.management.OperatingSystemMXBean",
- "java.lang", "OperatingSystem", defaultKeyProperties(),
- true, // singleton
- new MXBeanFetcher<com.sun.management.OperatingSystemMXBean>() {
- public List<com.sun.management.OperatingSystemMXBean> getMXBeans() {
- return getOSMXBeanList(com.sun.management.OperatingSystemMXBean.class);
- }
- }),
-
- /**
- * Unix operating system.
- */
- SUN_UNIX_OPERATING_SYSTEM(
- "com.sun.management.UnixOperatingSystemMXBean",
- "java.lang", "OperatingSystem", defaultKeyProperties(),
- true, // singleton
- new MXBeanFetcher<UnixOperatingSystemMXBean>() {
- public List<UnixOperatingSystemMXBean> getMXBeans() {
- return getOSMXBeanList(com.sun.management.UnixOperatingSystemMXBean.class);
- }
- }),
-
- /**
- * Diagnostic support for the HotSpot Virtual Machine.
- */
- HOTSPOT_DIAGNOSTIC(
- "com.sun.management.HotSpotDiagnosticMXBean",
- "com.sun.management", "HotSpotDiagnostic", defaultKeyProperties(),
- true, // singleton
- new MXBeanFetcher<HotSpotDiagnosticMXBean>() {
- public List<HotSpotDiagnosticMXBean> getMXBeans() {
- return Collections.singletonList(ManagementFactoryHelper.getDiagnosticMXBean());
- }
- });
-
-
- /**
- * A task that returns the MXBeans for a component.
- */
- interface MXBeanFetcher<T extends PlatformManagedObject> {
- public List<T> getMXBeans();
- }
-
- /*
- * Returns a list of the GC MXBeans of the given type.
- */
- private static <T extends GarbageCollectorMXBean>
- List<T> getGcMXBeanList(Class<T> gcMXBeanIntf) {
- List<GarbageCollectorMXBean> list =
- ManagementFactoryHelper.getGarbageCollectorMXBeans();
- List<T> result = new ArrayList<>(list.size());
- for (GarbageCollectorMXBean m : list) {
- if (gcMXBeanIntf.isInstance(m)) {
- result.add(gcMXBeanIntf.cast(m));
- }
- }
- return result;
- }
-
- /*
- * Returns the OS mxbean instance of the given type.
- */
- private static <T extends OperatingSystemMXBean>
- List<T> getOSMXBeanList(Class<T> osMXBeanIntf) {
- OperatingSystemMXBean m =
- ManagementFactoryHelper.getOperatingSystemMXBean();
- if (osMXBeanIntf.isInstance(m)) {
- return Collections.singletonList(osMXBeanIntf.cast(m));
- } else {
- return Collections.emptyList();
- }
- }
-
- private final String mxbeanInterfaceName;
- private final String domain;
- private final String type;
- private final Set<String> keyProperties;
- private final MXBeanFetcher<?> fetcher;
- private final PlatformComponent[] subComponents;
- private final boolean singleton;
-
- private PlatformComponent(String intfName,
- String domain, String type,
- Set<String> keyProperties,
- boolean singleton,
- MXBeanFetcher<?> fetcher,
- PlatformComponent... subComponents) {
- this.mxbeanInterfaceName = intfName;
- this.domain = domain;
- this.type = type;
- this.keyProperties = keyProperties;
- this.singleton = singleton;
- this.fetcher = fetcher;
- this.subComponents = subComponents;
- }
-
- private static Set<String> defaultKeyProps;
- private static Set<String> defaultKeyProperties() {
- if (defaultKeyProps == null) {
- defaultKeyProps = Collections.singleton("type");
- }
- return defaultKeyProps;
- }
-
- private static Set<String> keyProperties(String... keyNames) {
- Set<String> set = new HashSet<>();
- set.add("type");
- for (String s : keyNames) {
- set.add(s);
- }
- return set;
- }
-
- boolean isSingleton() {
- return singleton;
- }
-
- String getMXBeanInterfaceName() {
- return mxbeanInterfaceName;
- }
-
- @SuppressWarnings("unchecked")
- Class<? extends PlatformManagedObject> getMXBeanInterface() {
- try {
- // Lazy loading the MXBean interface only when it is needed
- return (Class<? extends PlatformManagedObject>)
- Class.forName(mxbeanInterfaceName, false,
- PlatformManagedObject.class.getClassLoader());
- } catch (ClassNotFoundException x) {
- throw new AssertionError(x);
- }
- }
-
- @SuppressWarnings("unchecked")
- <T extends PlatformManagedObject>
- List<T> getMXBeans(Class<T> mxbeanInterface)
- {
- return (List<T>) fetcher.getMXBeans();
- }
-
- <T extends PlatformManagedObject> T getSingletonMXBean(Class<T> mxbeanInterface)
- {
- if (!singleton)
- throw new IllegalArgumentException(mxbeanInterfaceName +
- " can have zero or more than one instances");
-
- List<T> list = getMXBeans(mxbeanInterface);
- assert list.size() == 1;
- return list.isEmpty() ? null : list.get(0);
- }
-
- <T extends PlatformManagedObject>
- T getSingletonMXBean(MBeanServerConnection mbs, Class<T> mxbeanInterface)
- throws java.io.IOException
- {
- if (!singleton)
- throw new IllegalArgumentException(mxbeanInterfaceName +
- " can have zero or more than one instances");
-
- // ObjectName of a singleton MXBean contains only domain and type
- assert keyProperties.size() == 1;
- String on = domain + ":type=" + type;
- return ManagementFactory.newPlatformMXBeanProxy(mbs,
- on,
- mxbeanInterface);
- }
-
- <T extends PlatformManagedObject>
- List<T> getMXBeans(MBeanServerConnection mbs, Class<T> mxbeanInterface)
- throws java.io.IOException
- {
- List<T> result = new ArrayList<>();
- for (ObjectName on : getObjectNames(mbs)) {
- result.add(ManagementFactory.
- newPlatformMXBeanProxy(mbs,
- on.getCanonicalName(),
- mxbeanInterface)
- );
- }
- return result;
- }
-
- private Set<ObjectName> getObjectNames(MBeanServerConnection mbs)
- throws java.io.IOException
- {
- String domainAndType = domain + ":type=" + type;
- if (keyProperties.size() > 1) {
- // if there are more than 1 key properties (i.e. other than "type")
- domainAndType += ",*";
- }
- ObjectName on = Util.newObjectName(domainAndType);
- Set<ObjectName> set = mbs.queryNames(on, null);
- for (PlatformComponent pc : subComponents) {
- set.addAll(pc.getObjectNames(mbs));
- }
- return set;
- }
-
- // a map from MXBean interface name to PlatformComponent
- private static Map<String, PlatformComponent> enumMap;
- private static synchronized void ensureInitialized() {
- if (enumMap == null) {
- enumMap = new HashMap<>();
- for (PlatformComponent pc: PlatformComponent.values()) {
- // Use String as the key rather than Class<?> to avoid
- // causing unnecessary class loading of management interface
- enumMap.put(pc.getMXBeanInterfaceName(), pc);
- }
- }
- }
-
- static boolean isPlatformMXBean(String cn) {
- ensureInitialized();
- return enumMap.containsKey(cn);
- }
-
- static <T extends PlatformManagedObject>
- PlatformComponent getPlatformComponent(Class<T> mxbeanInterface)
- {
- ensureInitialized();
- String cn = mxbeanInterface.getName();
- PlatformComponent pc = enumMap.get(cn);
- if (pc != null && pc.getMXBeanInterface() == mxbeanInterface)
- return pc;
- return null;
- }
-
- private static final long serialVersionUID = 6992337162326171013L;
-}
--- a/jdk/src/java.management/share/classes/sun/management/ExtendedPlatformComponent.java Thu Feb 05 11:42:39 2015 +0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.management;
-
-import java.util.Collections;
-import java.util.List;
-import java.lang.management.PlatformManagedObject;
-
-/**
- * Class to allow for an extended set of platform MXBeans
- */
-public final class ExtendedPlatformComponent {
- private ExtendedPlatformComponent() {} // Don't create any instances
-
- /**
- * Get the extended set of platform MXBeans that should be registered in the
- * platform MBeanServer, or an empty list if there are no such MXBeans.
- */
- public static List<? extends PlatformManagedObject> getMXBeans() {
- return Collections.emptyList();
- }
-
- /**
- * Returns the extended platform MXBean implementing the given
- * mxbeanInterface, or null if there is no such MXBean.
- */
- public static <T extends PlatformManagedObject>
- T getMXBean(Class<T> mxbeanInterface) {
- return null;
- }
-}
--- a/jdk/src/java.management/share/classes/sun/management/ManagementFactoryHelper.java Thu Feb 05 11:42:39 2015 +0800
+++ b/jdk/src/java.management/share/classes/sun/management/ManagementFactoryHelper.java Thu Feb 05 12:13:45 2015 +0100
@@ -42,14 +42,11 @@
import sun.util.logging.LoggingSupport;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import com.sun.management.DiagnosticCommandMBean;
import com.sun.management.HotSpotDiagnosticMXBean;
-import static java.lang.management.ManagementFactory.*;
-
/**
* ManagementFactoryHelper provides static factory methods to create
* instances of the management interface.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.management/share/classes/sun/management/spi/PlatformMBeanProvider.java Thu Feb 05 12:13:45 2015 +0100
@@ -0,0 +1,233 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.management.spi;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.ServiceLoader;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * The PlatformMBeanProvider class defines the abstract service interface
+ * that the {@link java.lang.management.ManagementFactory} will invoke to find,
+ * load, and register Platform MBeans.
+ *
+ * ManagementFactory loads the {@linkplain ServiceLoader#loadInstalled(java.lang.Class)
+ * installed providers} of this service interface and each provides the
+ * {@linkplain PlatformComponent platform components} that defines MXBean
+ * or DynamicMBean to be registered in the platform MBeanServer.
+ *
+ * A {@code PlatformMBeanProvider} will implement the {@code getPlatformComponentList()}
+ * method to return the list of {@code PlatformComponents} it provides.
+ */
+public abstract class PlatformMBeanProvider {
+ /**
+ * {@code PlatformComponent} models MBeans of a management interface supported
+ * by the platform.
+ *
+ * If a PlatformComponent models a singleton MBean, the {@link #getObjectNamePattern()
+ * ObjectName pattern} must be the {@link
+ * javax.management.ObjectName#getCanonicalName() canonical name} of that
+ * singleton MBean. Otherwise, it must be an ObjectName pattern
+ * that can be used to query the MBeans for this
+ * PlatformComponent registered in a {@code MBeanServer}.
+ * <br>
+ * The {@link #getObjectNamePattern() ObjectName pattern} serves as a unique
+ * key for identifying the instance of PlatformComponent. It is thus illegal
+ * for a given {@link PlatformMBeanProvider} to export several instance of
+ * PlatformComponent with the same
+ * {@link #getObjectNamePattern() ObjectName pattern} string.
+ * <br>
+ * If two different provider instances export a PlatformComponent for the
+ * same ObjectName pattern, only the PlatformComponent instance of the first
+ * provider will be taken into account.
+ *
+ * @param <T> The higher level interface for which the MBeans modeled by
+ * this object should be recognized. For instance, for the {@link
+ * java.lang.management.ManagementFactory#getOperatingSystemMXBean()
+ * Operating System MXBean}, this should be {@link
+ * java.lang.management.OperatingSystemMXBean
+ * java.lang.management.OperatingSystemMXBean}.
+ */
+ public interface PlatformComponent<T> {
+ /**
+ * Returns the names of the management interfaces implemented by the
+ * MBeans modeled by this {@code PlatformComponent}.
+ *
+ * @implNote
+ * When {@link java.lang.management.ManagementFactory#getPlatformMXBean(java.lang.Class)
+ * ManagementFactory.getPlatformMXBean(mxbeanInterface)} or {@link
+ * java.lang.management.ManagementFactory#getPlatformMXBeans(java.lang.Class)
+ * ManagementFactory.getPlatformMXBeans(mxbeanInterface)} are invoked,
+ * this PlatformComponent instance will match only if the name of the
+ * given {@code mxbeanInterface} is found in this list.
+ *
+ * @return the names of the management interfaces exported by the MBeans
+ * modeled by this object.
+ */
+ public Set<String> mbeanInterfaceNames();
+
+ /**
+ * A map from ObjectName string to the MBean instance this
+ * {@code PlatformComponent} creates.
+ *
+ * @implNote
+ * If {@link #shouldRegister()} is {@code true}, this method
+ * will be called when the {@link java.lang.management.ManagementFactory
+ * #getPlatformMBeanServer() Platform MBeanServer} is initialized.
+ * By default, this method will also be called by {@link
+ * #getMBeans(java.lang.Class)}, when {@link
+ * java.lang.management.ManagementFactory#getPlatformMXBean(java.lang.Class)
+ * ManagementFactory.getPlatformMXBean(mxbeanInterface)} or {@link
+ * java.lang.management.ManagementFactory#getPlatformMXBeans(java.lang.Class)
+ * ManagementFactory.getPlatformMXBeans(mxbeanInterface)} are invoked,
+ * and when the name of the given {@code mxbeanInterface} is contained
+ * in the names of management interfaces returned by {@link
+ * #mbeanInterfaceNames()}.
+ *
+ * @return A map with, for each MBean, the ObjectName string as key
+ * and the MBean as value.
+ */
+ public Map<String, T> nameToMBeanMap();
+
+ /**
+ * An ObjectName pattern uniquely identifies the MBeans
+ * modeled by this {@code PlatformComponent}.
+ * If this instance models a singleton MBean, this must be
+ * the {@link
+ * javax.management.ObjectName#getCanonicalName() canonical name}
+ * of that singleton MBean.
+ *
+ * @return An ObjectName pattern uniquely identifies the MBeans
+ * modeled by this instance.
+ */
+ public String getObjectNamePattern();
+
+ /**
+ * Returns {@code true} if this {@code PlatformComponent} models
+ * a singleton MBean. By default, {@code true} is assumed.
+ *
+ * @return {@code true} if this instance models a singleton MBean.
+ */
+ public default boolean isSingleton() {
+ return true;
+ }
+
+ /**
+ * Returns {@code true} if the MBeans modeled by this {@code PlatformComponent}
+ * should automatically be registered in the {@link
+ * java.lang.management.ManagementFactory#getPlatformMBeanServer()
+ * Platform MBeanServer}. By default, {@code true} is assumed.
+ *
+ * @return {@code true} if the MBeans modeled by this instance should
+ * automatically be registered in the Platform MBeanServer.
+ */
+ public default boolean shouldRegister() {
+ return true;
+ }
+
+ /**
+ * The set of interfaces implemented by the MBeans modeled
+ * by this {@code PlatformComponent}.
+ *
+ * @implNote
+ * {@link java.lang.management.ManagementFactory#getPlatformManagementInterfaces()
+ * ManagementFactory.getPlatformManagementInterfaces()} calls this
+ * method to find the management interfaces supported by the platform.
+ *
+ * @return The set of interfaces implemented by the MBeans modeled
+ * by this instance
+ */
+ public Set<Class<? extends T>> mbeanInterfaces();
+
+ /**
+ * Return the list of MBeans that implement the given {@code mbeanIntf}
+ * modeled by this {@code PlatformComponent}. This method returns an
+ * empty list if no MBean implements the given {@code mbeanIntf}.
+ *
+ * @implNote This method will be called when {@link
+ * java.lang.management.ManagementFactory#getPlatformMXBean(java.lang.Class)
+ * ManagementFactory.getPlatformMXBean(mbeanIntf)} or {@link
+ * java.lang.management.ManagementFactory#getPlatformMXBeans(java.lang.Class)
+ * ManagementFactory.getPlatformMXBeans(mbeanIntf)} are invoked.
+ * By default it first checks whether the specified {@code mbeanIntf}
+ * name is contained in the returned list from the {@link #mbeanInterfaceNames()}
+ * method. If yes, it proceeds and calls
+ * {@link #mbeans().values()} and filters out all
+ * MBeans which are not instances of the given {@code mbeanIntf}.
+ * Otherwise, it returns an empty list.
+ *
+ * @param mbeanIntf A management interface.
+ * @return A (possibly empty) list of MBeans implementing the given
+ * {@code mbeanIntf}.
+ */
+ public default <I> List<? extends I> getMBeans(Class<I> mbeanIntf) {
+ List<I> list;
+
+ if (!mbeanInterfaceNames().contains(mbeanIntf.getName())) {
+ list = Collections.emptyList();
+ } else {
+ list = nameToMBeanMap().values().stream()
+ .filter(mbeanIntf::isInstance)
+ .map(mbeanIntf::cast)
+ .collect(Collectors.toList());
+ }
+ return list;
+ }
+ }
+
+ /**
+ * Instantiates a new PlatformMBeanProvider.
+ *
+ * @throws SecurityException if the subclass (and calling code) does not
+ * have {@code RuntimePermission("sun.management.spi.PlatformMBeanProvider", "subclass")}
+ */
+ protected PlatformMBeanProvider () {
+ this(checkSubclassPermission());
+ }
+
+ private PlatformMBeanProvider(Void unused) {
+ }
+
+ /**
+ * Returns a list of PlatformComponent instances describing the Platform
+ * MBeans provided by this provider.
+ *
+ * @return a list of PlatformComponent instances describing the Platform
+ * MBeans provided by this provider.
+ */
+ public abstract List<PlatformComponent<?>> getPlatformComponentList();
+
+ private static Void checkSubclassPermission() {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(new RuntimePermission(PlatformMBeanProvider.class.getName(), "subclass"));
+ }
+ return null;
+ }
+}