8212795: ThreadInfoCompositeData.toCompositeData fails to map ThreadInfo to CompositeData
Reviewed-by: dfuchs
--- 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;