JDK-7074616 : java.lang.management.ManagementFactory.getPlatformManagementInterfaces fails
  • Type: Bug
  • Component: core-svc
  • Sub-Component: java.lang.management
  • Affected Version: 7
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: windows_7
  • CPU: x86
  • Submitted: 2011-08-03
  • Updated: 2019-08-16
  • Resolved: 2012-04-19
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7 JDK 8
7u6 b06Fixed 8Fixed
Description
FULL PRODUCT VERSION :
java version "1.7.0"
Java(TM) SE Runtime Environment (build 1.7.0-b147)
Java HotSpot(TM) 64-Bit Server VM (build 21.0-b17, mixed mode)


ADDITIONAL OS VERSION INFORMATION :
Linux, windows 7 64 bit, verified bug in openjdk source code

A DESCRIPTION OF THE PROBLEM :
getPlatformManagementInterfaces throws an exception when it attempts to populate  a TreeSet of Class objects.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
The below class will always throw an exception:

public class Fail
{
    public static void main(String[] args)
    {
        for (Class<?> c : java.lang.management.ManagementFactory.getPlatformManagementInterfaces())
        {
            System.out.println(c);
        }
    }
}


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The method should successfully return the collection of interfaces it says it will return instead of always failing.
ACTUAL -
$ javac -cp . Fail.java && java -cp . Fail
Exception in thread "main" java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.Comparable
        at java.util.TreeMap.compare(TreeMap.java:1188)
        at java.util.TreeMap.put(TreeMap.java:531)
        at java.util.TreeSet.add(TreeSet.java:255)
        at java.lang.management.ManagementFactory.getPlatformManagementInterfaces(ManagementFactory.java:792)
        at Fail.main(Fail.java:5)


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
public class Fail
{
    public static void main(String[] args)
    {
        for (Class<?> c : java.lang.management.ManagementFactory.getPlatformManagementInterfaces())
        {
            System.out.println(c);
        }
    }
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
The data being accessed cannot be retrieved from outside the java.lang.management package.  The fix should be trivial (either use a HashSet instead of a TreeSet, or if sorting is really deemed desirable, provide a comparator for the treeset to use.)

Comments
SUGGESTED FIX --- old/src/share/classes/java/lang/management/ManagementFactory.java Thu Mar 8 15:43:50 2012 +++ new/src/share/classes/java/lang/management/ManagementFactory.java Thu Mar 8 15:43:49 2012 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -42,7 +42,7 @@ import java.util.Collections; import java.util.List; import java.util.Set; -import java.util.TreeSet; +import java.util.HashSet; import java.security.AccessController; import java.security.Permission; import java.security.PrivilegedAction; @@ -787,7 +787,7 @@ getPlatformManagementInterfaces() { Set<Class<? extends PlatformManagedObject>> result = - new TreeSet<>(); + new HashSet<>(); for (PlatformComponent component: PlatformComponent.values()) { result.add(component.getMXBeanInterface()); } --- /dev/null Thu Mar 8 15:43:52 2012 +++ new/test/java/lang/management/ManagementFactory/GetPlatformManagementInterfaces.java Thu Mar 8 15:43:51 2012 @@ -0,0 +1,78 @@ +/* + * Copyright (c) 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. + * + * 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. + */ + +/* + * @test + * @bug 7074616 + * @summary Basic unit test of the + * ManagementFactory.getPlatformManagementInterfaces() method + * @author Frederic Parain + * + * @run main GetPlatformManagementInterfaces + */ + +import java.lang.management.*; +import java.io.IOException; +import java.util.*; +import javax.management.*; + +import static java.lang.management.ManagementFactory.*; + +public class GetPlatformManagementInterfaces { + + private static enum ManagementInterfaces { + CLASS_LOADING_MXBEAN(ClassLoadingMXBean.class), + COMPILATION_MXBEAN(CompilationMXBean.class), + MEMORY_MXBEAN(MemoryMXBean.class), + OPERATING_SYSTEM_MXBEAN(OperatingSystemMXBean.class), + RUNTIME_MXBEAN(RuntimeMXBean.class), + THREAD_MXBEAN(ThreadMXBean.class), + GARBAGE_COLLECTOR_MXBEAN(GarbageCollectorMXBean.class), + MEMORY_MANAGER_MXBEAN(MemoryManagerMXBean.class), + MEMORY_POOL_MXBEAN(MemoryPoolMXBean.class); + + + private final Class<? extends PlatformManagedObject> managementInterface; + private ManagementInterfaces(Class<? extends PlatformManagedObject> minterface) { + managementInterface = minterface; + } + public Class<? extends PlatformManagedObject> getManagementInterface() { + return managementInterface; + } + + }; + + public static void main(String[] args) { + Set<Class<? extends PlatformManagedObject>> interfaces = + ManagementFactory.getPlatformManagementInterfaces(); + for(Class<? extends PlatformManagedObject> pom : interfaces) { + List<? extends PlatformManagedObject> list = + ManagementFactory.getPlatformMXBeans(pom); + } + for(ManagementInterfaces mi : ManagementInterfaces.values()) { + if(!interfaces.contains(mi.getManagementInterface())) { + throw new RuntimeException(mi.getManagementInterface() + " not in ManagementInterfaces set"); + } + } + } +}
16-03-2012

EVALUATION The getPlatformManagementInterfaces() method tries to populate a TreeSet with classes that don't implement the Comparable interface. The return type of the method is Set<Class<? extends PlatformManagedObject>>, so no need to have a sorted collection. The fix replaces the use of a TreeSet with a HashSet.
15-03-2012