--- old/src/java.management/share/classes/sun/management/LockInfoCompositeData.java 2018-10-24 15:06:15.000000000 -0700 +++ new/src/java.management/share/classes/sun/management/LockInfoCompositeData.java 2018-10-24 15:06:14.000000000 -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 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. --- old/src/java.management/share/classes/sun/management/MonitorInfoCompositeData.java 2018-10-24 15:06:16.000000000 -0700 +++ new/src/java.management/share/classes/sun/management/MonitorInfoCompositeData.java 2018-10-24 15:06:16.000000000 -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 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); } --- old/src/java.management/share/classes/sun/management/StackTraceElementCompositeData.java 2018-10-24 15:06:18.000000000 -0700 +++ new/src/java.management/share/classes/sun/management/StackTraceElementCompositeData.java 2018-10-24 15:06:17.000000000 -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 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 --- old/src/java.management/share/classes/sun/management/ThreadInfoCompositeData.java 2018-10-24 15:06:20.000000000 -0700 +++ new/src/java.management/share/classes/sun/management/ThreadInfoCompositeData.java 2018-10-24 15:06:19.000000000 -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 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 compositeTypes = initCompositeTypes(); /* * Returns CompositeType of the given runtime version @@ -382,7 +367,7 @@ static Map initCompositeTypes() { Map 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; --- old/test/jdk/java/lang/management/CompositeData/ThreadInfoCompositeData.java 2018-10-24 15:06:21.000000000 -0700 +++ new/test/jdk/java/lang/management/CompositeData/ThreadInfoCompositeData.java 2018-10-24 15:06:21.000000000 -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;