8212795: ThreadInfoCompositeData.toCompositeData fails to map ThreadInfo to CompositeData
authormchung
Thu, 25 Oct 2018 10:57:42 -0700
changeset 52288 2b29df6dfa68
parent 52287 2f6c9127dd97
child 52289 04e6910792b3
8212795: ThreadInfoCompositeData.toCompositeData fails to map ThreadInfo to CompositeData Reviewed-by: dfuchs
src/java.management/share/classes/sun/management/LockInfoCompositeData.java
src/java.management/share/classes/sun/management/MonitorInfoCompositeData.java
src/java.management/share/classes/sun/management/StackTraceElementCompositeData.java
src/java.management/share/classes/sun/management/ThreadInfoCompositeData.java
test/jdk/java/lang/management/CompositeData/ThreadInfoCompositeData.java
--- a/src/java.management/share/classes/sun/management/LockInfoCompositeData.java	Thu Oct 25 10:56:45 2018 -0700
+++ b/src/java.management/share/classes/sun/management/LockInfoCompositeData.java	Thu Oct 25 10:57:42 2018 -0700
@@ -26,6 +26,7 @@
 package sun.management;
 
 import java.lang.management.LockInfo;
+import java.util.Map;
 import javax.management.openmbean.CompositeType;
 import javax.management.openmbean.CompositeData;
 import javax.management.openmbean.CompositeDataSupport;
@@ -57,17 +58,13 @@
     }
 
     protected CompositeData getCompositeData() {
-        // CONTENTS OF THIS ARRAY MUST BE SYNCHRONIZED WITH
-        // LOCK_INFO_ATTRIBUTES!
-        final Object[] lockInfoItemValues = {
-            new String(lock.getClassName()),
-            lock.getIdentityHashCode(),
-        };
+        Map<String,Object> items = Map.of(
+            CLASS_NAME,         lock.getClassName(),
+            IDENTITY_HASH_CODE, lock.getIdentityHashCode()
+        );
 
         try {
-            return new CompositeDataSupport(LOCK_INFO_COMPOSITE_TYPE,
-                                            LOCK_INFO_ATTRIBUTES,
-                                            lockInfoItemValues);
+            return new CompositeDataSupport(LOCK_INFO_COMPOSITE_TYPE, items);
         } catch (OpenDataException e) {
             // Should never reach here
             throw Util.newException(e);
@@ -91,10 +88,6 @@
 
     private static final String CLASS_NAME         = "className";
     private static final String IDENTITY_HASH_CODE = "identityHashCode";
-    private static final String[] LOCK_INFO_ATTRIBUTES = {
-        CLASS_NAME,
-        IDENTITY_HASH_CODE,
-    };
 
     /*
      * Returns a LockInfo object mapped from the given CompositeData.
--- a/src/java.management/share/classes/sun/management/MonitorInfoCompositeData.java	Thu Oct 25 10:56:45 2018 -0700
+++ b/src/java.management/share/classes/sun/management/MonitorInfoCompositeData.java	Thu Oct 25 10:57:42 2018 -0700
@@ -26,6 +26,8 @@
 package sun.management;
 
 import java.lang.management.MonitorInfo;
+import java.util.HashMap;
+import java.util.Map;
 import javax.management.openmbean.CompositeType;
 import javax.management.openmbean.CompositeData;
 import javax.management.openmbean.CompositeDataSupport;
@@ -54,31 +56,18 @@
     }
 
     protected CompositeData getCompositeData() {
-        // CONTENTS OF THIS ARRAY MUST BE SYNCHRONIZED WITH
-        // MONITOR_INFO_ATTRIBUTES!
-
-        int len = MONITOR_INFO_ATTRIBUTES.length;
-        Object[] values = new Object[len];
-        CompositeData li = LockInfoCompositeData.toCompositeData(lock);
-
-        for (int i = 0; i < len; i++) {
-            String item = MONITOR_INFO_ATTRIBUTES[i];
-            if (item.equals(LOCKED_STACK_FRAME)) {
-                StackTraceElement ste = lock.getLockedStackFrame();
-                values[i] = (ste != null ? StackTraceElementCompositeData.
-                                               toCompositeData(ste)
-                                         : null);
-            } else if (item.equals(LOCKED_STACK_DEPTH)) {
-                values[i] = lock.getLockedStackDepth();
-            } else {
-                values[i] = li.get(item);
-            }
-        }
+        StackTraceElement ste = lock.getLockedStackFrame();
+        CompositeData steCData = ste != null ? StackTraceElementCompositeData.toCompositeData(ste)
+                                             : null;
+        // values may be null; can't use Map.of
+        Map<String,Object> items = new HashMap<>();
+        items.put(CLASS_NAME,         lock.getClassName());
+        items.put(IDENTITY_HASH_CODE, lock.getIdentityHashCode());
+        items.put(LOCKED_STACK_FRAME, steCData);
+        items.put(LOCKED_STACK_DEPTH, lock.getLockedStackDepth());
 
         try {
-            return new CompositeDataSupport(MONITOR_INFO_COMPOSITE_TYPE,
-                                            MONITOR_INFO_ATTRIBUTES,
-                                            values);
+            return new CompositeDataSupport(MONITOR_INFO_COMPOSITE_TYPE, items);
         } catch (OpenDataException e) {
             // Should never reach here
             throw new AssertionError(e);
@@ -126,10 +115,6 @@
         return V6_COMPOSITE_TYPE;
     }
 
-    static CompositeType compositeType() {
-        return MONITOR_INFO_COMPOSITE_TYPE;
-    }
-
     public static String getClassName(CompositeData cd) {
         return getString(cd, CLASS_NAME);
     }
--- a/src/java.management/share/classes/sun/management/StackTraceElementCompositeData.java	Thu Oct 25 10:56:45 2018 -0700
+++ b/src/java.management/share/classes/sun/management/StackTraceElementCompositeData.java	Thu Oct 25 10:57:42 2018 -0700
@@ -31,6 +31,8 @@
 import javax.management.openmbean.OpenDataException;
 import javax.management.openmbean.OpenType;
 import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.stream.Stream;
 
 /**
@@ -75,24 +77,19 @@
     }
 
     protected CompositeData getCompositeData() {
-        // CONTENTS OF THIS ARRAY MUST BE SYNCHRONIZED WITH
-        // STACK_TRACE_ELEMENT_ATTRIBUTES!
-        final Object[] stackTraceElementItemValues = {
-            // JDK 5 attributes
-            ste.getClassName(),
-            ste.getMethodName(),
-            ste.getFileName(),
-            ste.getLineNumber(),
-            ste.isNativeMethod(),
-            // JDK 9 attributes
-            ste.getClassLoaderName(),
-            ste.getModuleName(),
-            ste.getModuleVersion(),
-        };
+        // values may be null; so can't use Map.of
+        Map<String,Object> items = new HashMap<>();
+        items.put(CLASS_LOADER_NAME, ste.getClassLoaderName());
+        items.put(MODULE_NAME,       ste.getModuleName());
+        items.put(MODULE_VERSION,    ste.getModuleVersion());
+        items.put(CLASS_NAME,        ste.getClassName());
+        items.put(METHOD_NAME,       ste.getMethodName());
+        items.put(FILE_NAME,         ste.getFileName());
+        items.put(LINE_NUMBER,       ste.getLineNumber());
+        items.put(NATIVE_METHOD,     ste.isNativeMethod());
+
         try {
-            return new CompositeDataSupport(STACK_TRACE_ELEMENT_COMPOSITE_TYPE,
-                                            STACK_TRACE_ELEMENT_ATTRIBUTES,
-                                            stackTraceElementItemValues);
+            return new CompositeDataSupport(STACK_TRACE_ELEMENT_COMPOSITE_TYPE, items);
         } catch (OpenDataException e) {
             // Should never reach here
             throw new AssertionError(e);
@@ -123,10 +120,6 @@
         MODULE_VERSION,
     };
 
-    private static final String[] STACK_TRACE_ELEMENT_ATTRIBUTES =
-        Stream.of(V5_ATTRIBUTES, V9_ATTRIBUTES).flatMap(Arrays::stream)
-              .toArray(String[]::new);
-
     private static final CompositeType STACK_TRACE_ELEMENT_COMPOSITE_TYPE;
     private static final CompositeType V5_COMPOSITE_TYPE;
     static {
@@ -153,9 +146,6 @@
     static CompositeType v5CompositeType() {
         return V5_COMPOSITE_TYPE;
     }
-    static CompositeType compositeType() {
-        return STACK_TRACE_ELEMENT_COMPOSITE_TYPE;
-    }
 
     /**
      * Validate if the input CompositeData has the expected
--- a/src/java.management/share/classes/sun/management/ThreadInfoCompositeData.java	Thu Oct 25 10:56:45 2018 -0700
+++ b/src/java.management/share/classes/sun/management/ThreadInfoCompositeData.java	Thu Oct 25 10:57:42 2018 -0700
@@ -75,8 +75,7 @@
     protected CompositeData getCompositeData() {
         // Convert StackTraceElement[] to CompositeData[]
         StackTraceElement[] stackTrace = threadInfo.getStackTrace();
-        CompositeData[] stackTraceData =
-            new CompositeData[stackTrace.length];
+        CompositeData[] stackTraceData = new CompositeData[stackTrace.length];
         for (int i = 0; i < stackTrace.length; i++) {
             StackTraceElement ste = stackTrace[i];
             stackTraceData[i] = StackTraceElementCompositeData.toCompositeData(ste);
@@ -88,48 +87,42 @@
 
         // Convert LockInfo[] and MonitorInfo[] to CompositeData[]
         LockInfo[] lockedSyncs = threadInfo.getLockedSynchronizers();
-        CompositeData[] lockedSyncsData =
-            new CompositeData[lockedSyncs.length];
+        CompositeData[] lockedSyncsData = new CompositeData[lockedSyncs.length];
         for (int i = 0; i < lockedSyncs.length; i++) {
             LockInfo li = lockedSyncs[i];
             lockedSyncsData[i] = LockInfoCompositeData.toCompositeData(li);
         }
 
         MonitorInfo[] lockedMonitors = threadInfo.getLockedMonitors();
-        CompositeData[] lockedMonitorsData =
-            new CompositeData[lockedMonitors.length];
+        CompositeData[] lockedMonitorsData = new CompositeData[lockedMonitors.length];
         for (int i = 0; i < lockedMonitors.length; i++) {
             MonitorInfo mi = lockedMonitors[i];
             lockedMonitorsData[i] = MonitorInfoCompositeData.toCompositeData(mi);
         }
 
-        // CONTENTS OF THIS ARRAY MUST BE SYNCHRONIZED WITH
-        // THREAD_INFO_ATTRIBUTES!
-        final Object[] threadInfoItemValues = {
-            threadInfo.getThreadId(),
-            threadInfo.getThreadName(),
-            threadInfo.getThreadState().name(),
-            threadInfo.getBlockedTime(),
-            threadInfo.getBlockedCount(),
-            threadInfo.getWaitedTime(),
-            threadInfo.getWaitedCount(),
-            lockInfoData,
-            threadInfo.getLockName(),
-            threadInfo.getLockOwnerId(),
-            threadInfo.getLockOwnerName(),
-            stackTraceData,
-            threadInfo.isSuspended(),
-            threadInfo.isInNative(),
-            lockedMonitorsData,
-            lockedSyncsData,
-            threadInfo.isDaemon(),
-            threadInfo.getPriority(),
-        };
+        // values may be null; can't use Map.of
+        Map<String,Object> items = new HashMap<>();
+        items.put(THREAD_ID,        threadInfo.getThreadId());
+        items.put(THREAD_NAME,      threadInfo.getThreadName());
+        items.put(THREAD_STATE,     threadInfo.getThreadState().name());
+        items.put(BLOCKED_TIME,     threadInfo.getBlockedTime());
+        items.put(BLOCKED_COUNT,    threadInfo.getBlockedCount());
+        items.put(WAITED_TIME,      threadInfo.getWaitedTime());
+        items.put(WAITED_COUNT,     threadInfo.getWaitedCount());
+        items.put(LOCK_INFO,        lockInfoData);
+        items.put(LOCK_NAME,        threadInfo.getLockName());
+        items.put(LOCK_OWNER_ID,    threadInfo.getLockOwnerId());
+        items.put(LOCK_OWNER_NAME,  threadInfo.getLockOwnerName());
+        items.put(STACK_TRACE,      stackTraceData);
+        items.put(SUSPENDED,        threadInfo.isSuspended());
+        items.put(IN_NATIVE,        threadInfo.isInNative());
+        items.put(LOCKED_MONITORS,  lockedMonitorsData);
+        items.put(LOCKED_SYNCS,     lockedSyncsData);
+        items.put(DAEMON,           threadInfo.isDaemon());
+        items.put(PRIORITY,         threadInfo.getPriority());
 
         try {
-            return new CompositeDataSupport(compositeType(),
-                                            THREAD_INFO_ATTRIBTUES,
-                                            threadInfoItemValues);
+            return new CompositeDataSupport(ThreadInfoCompositeTypes.ofVersion(RUNTIME_VERSION), items);
         } catch (OpenDataException e) {
             // Should never reach here
             throw new AssertionError(e);
@@ -183,10 +176,6 @@
         PRIORITY,
     };
 
-    private static final String[] THREAD_INFO_ATTRIBTUES =
-        Stream.of(V5_ATTRIBUTES, V6_ATTRIBUTES, V9_ATTRIBUTES)
-              .flatMap(Arrays::stream).toArray(String[]::new);
-
     public long threadId() {
         return getLong(cdata, THREAD_ID);
     }
@@ -365,12 +354,8 @@
         }
     }
 
-    public static CompositeType compositeType() {
-        return ThreadInfoCompositeTypes.compositeTypes.get(0);
-    }
-
+    static final int RUNTIME_VERSION =  Runtime.version().feature();
     static class ThreadInfoCompositeTypes {
-        static final int CURRENT =  Runtime.version().feature();
         static final Map<Integer, CompositeType> compositeTypes = initCompositeTypes();
         /*
          * Returns CompositeType of the given runtime version
@@ -382,7 +367,7 @@
         static Map<Integer, CompositeType> initCompositeTypes() {
             Map<Integer, CompositeType> types = new HashMap<>();
             CompositeType ctype = initCompositeType();
-            types.put(CURRENT, ctype);
+            types.put(RUNTIME_VERSION, ctype);
             types.put(5, initV5CompositeType(ctype));
             types.put(6, initV6CompositeType(ctype));
             return types;
--- a/test/jdk/java/lang/management/CompositeData/ThreadInfoCompositeData.java	Thu Oct 25 10:56:45 2018 -0700
+++ b/test/jdk/java/lang/management/CompositeData/ThreadInfoCompositeData.java	Thu Oct 25 10:57:42 2018 -0700
@@ -29,8 +29,9 @@
  *          the input CompositeData is invalid.
  * @author  Mandy Chung
  *
+ * @modules java.management/sun.management
  * @build ThreadInfoCompositeData OpenTypeConverter
- * @run main ThreadInfoCompositeData
+ * @run testng/othervm ThreadInfoCompositeData
  */
 
 
@@ -42,6 +43,9 @@
 import java.util.Objects;
 import java.util.stream.Stream;
 
+import org.testng.annotations.Test;
+import static org.testng.Assert.*;
+
 public class ThreadInfoCompositeData {
     private static String lockClassName = "myClass";
     private static int lockIdentityHashCode = 123456;
@@ -50,24 +54,7 @@
     private static LockInfo lockInfo =
         new LockInfo(lockClassName, lockIdentityHashCode);
 
-    public static void main(String[] argv) throws Exception {
-        // A valid CompositeData is passed to ThreadInfo
-        createGoodCompositeData();
-        // A valid CompositeData for JDK 5 ThreadInfo
-        // is passed to ThreadInfo
-        createV5ThreadInfo();
-        // ThreadInfo of version N can accept lockedMonitors of version >= N
-        withNewMonitorInfoCompositeData();
-
-        // An invalid CompositeData is passed to ThreadInfo.from()
-        badNameCompositeData();
-        badTypeCompositeData();
-        badMissingCompositeData();
-        withV5StackTraceCompositeData();
-        withInvalidMonitorInfoCompositeData();
-        System.out.println("Test passed");
-    }
-
+    @Test
     public static void createGoodCompositeData() throws Exception {
         CompositeData cd = Factory.makeThreadInfoCompositeData();
         ThreadInfo info = ThreadInfo.from(cd);
@@ -77,6 +64,7 @@
     /*
      * An invalid CompositeData with JDK 9 attributes but missing JDK 6 attributes
      */
+    @Test
     public static void badMissingCompositeData() throws Exception {
         CompositeData cd = Factory.makeCompositeDataMissingV6();
         try {
@@ -92,6 +80,7 @@
     /*
      * Current version of ThreadInfo but an older version of StackTraceElement
      */
+    @Test
     public static void withV5StackTraceCompositeData() throws Exception {
         CompositeData cd = Factory.makeThreadInfoWithV5StackTrace();
         try {
@@ -104,6 +93,7 @@
      * Current version of ThreadInfo but an older version of MonitorInfo
      * and the value of "lockedStackFrame" attribute is null.
      */
+    @Test
     public static void withInvalidMonitorInfoCompositeData() throws Exception {
         CompositeData cd = Factory.makeThreadInfoWithIncompatibleMonitorInfo();
 
@@ -128,6 +118,7 @@
     /*
      * ThreadInfo of version N can accept lockedMonitors of version >= N
      */
+    @Test
     public static void withNewMonitorInfoCompositeData() throws Exception {
         CompositeData cd = Factory.makeThreadInfoWithNewMonitorInfo();
         ThreadInfo info = ThreadInfo.from(cd);
@@ -137,11 +128,24 @@
     /*
      * Test CompositeData representing JDK 5 ThreadInfo
      */
+    @Test
     public static void createV5ThreadInfo() throws Exception {
         CompositeData cd = Factory.makeThreadInfoV5CompositeData();
         ThreadInfo info = ThreadInfo.from(cd);
         checkThreadInfoV5(info);
-   }
+    }
+
+    /*
+     * Test ThreadInfoCompositeData.toCompositeData
+     */
+    @Test
+    public static void internalToCompositeData() throws Exception {
+        CompositeData cd = Factory.makeThreadInfoCompositeData();
+        ThreadInfo info = ThreadInfo.from(cd);
+        cd = sun.management.ThreadInfoCompositeData.toCompositeData(info);
+        info = ThreadInfo.from(cd);
+        checkThreadInfo(info);
+    }
 
    static void checkThreadInfoV5(ThreadInfo info) {
        Object[] values = Factory.VALUES;
@@ -262,6 +266,7 @@
         }
     }
 
+    @Test
     public static void badNameCompositeData() throws Exception {
         CompositeData cd = Factory.makeCompositeDataWithBadNames();
         try {
@@ -270,6 +275,7 @@
         } catch (IllegalArgumentException e) { }
     }
 
+    @Test
     public static void badTypeCompositeData() throws Exception {
         CompositeData cd = Factory.makeCompositeDataWithBadTypes();
 
@@ -300,7 +306,7 @@
     private static final int DAEMON = 16;
     private static final int PRIORITY = 17;
 
-    static class Factory {
+    private static class Factory {
 
         static final CompositeType STE_COMPOSITE_TYPE;
         static final CompositeType LOCK_INFO_COMPOSITE_TYPE;