8065213: Specify and implement PlatformMBeanProvider for looking for all platform MBeans
authorsjiang
Thu, 05 Feb 2015 12:13:45 +0100
changeset 28775 d786aae24263
parent 28774 052832e70254
child 28776 4153595a6ced
8065213: Specify and implement PlatformMBeanProvider for looking for all platform MBeans Reviewed-by: dfuchs, mchung, jbachorik
jdk/src/java.management/share/classes/META-INF/services/sun.management.spi.PlatformMBeanProvider
jdk/src/java.management/share/classes/com/sun/management/internal/PlatformMBeanProviderImpl.java
jdk/src/java.management/share/classes/java/lang/management/DefaultPlatformMBeanProvider.java
jdk/src/java.management/share/classes/java/lang/management/ManagementFactory.java
jdk/src/java.management/share/classes/java/lang/management/PlatformComponent.java
jdk/src/java.management/share/classes/sun/management/ExtendedPlatformComponent.java
jdk/src/java.management/share/classes/sun/management/ManagementFactoryHelper.java
jdk/src/java.management/share/classes/sun/management/spi/PlatformMBeanProvider.java
--- /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;
+    }
+}