8212795: ThreadInfoCompositeData.toCompositeData fails to map ThreadInfo to CompositeData

Reviewed-by: dfuchs
This commit is contained in:
Mandy Chung 2018-10-25 10:57:42 -07:00
parent 85598bc90f
commit d523a17e80
5 changed files with 85 additions and 126 deletions

View File

@ -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 @@ public class LockInfoCompositeData extends LazyCompositeData {
}
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 @@ public class LockInfoCompositeData extends LazyCompositeData {
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.

View File

@ -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 @@ public class MonitorInfoCompositeData extends LazyCompositeData {
}
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 @@ public class MonitorInfoCompositeData extends LazyCompositeData {
return V6_COMPOSITE_TYPE;
}
static CompositeType compositeType() {
return MONITOR_INFO_COMPOSITE_TYPE;
}
public static String getClassName(CompositeData cd) {
return getString(cd, CLASS_NAME);
}

View File

@ -31,6 +31,8 @@ import javax.management.openmbean.CompositeDataSupport;
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 @@ public class StackTraceElementCompositeData extends LazyCompositeData {
}
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 @@ public class StackTraceElementCompositeData extends LazyCompositeData {
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 @@ public class StackTraceElementCompositeData extends LazyCompositeData {
static CompositeType v5CompositeType() {
return V5_COMPOSITE_TYPE;
}
static CompositeType compositeType() {
return STACK_TRACE_ELEMENT_COMPOSITE_TYPE;
}
/**
* Validate if the input CompositeData has the expected

View File

@ -75,8 +75,7 @@ public class ThreadInfoCompositeData extends LazyCompositeData {
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 @@ public class ThreadInfoCompositeData extends LazyCompositeData {
// 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 @@ public class ThreadInfoCompositeData extends LazyCompositeData {
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 class ThreadInfoCompositeData extends LazyCompositeData {
}
}
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 @@ public class ThreadInfoCompositeData extends LazyCompositeData {
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;

View File

@ -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.Arrays;
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 @@ public class ThreadInfoCompositeData {
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 @@ public class ThreadInfoCompositeData {
/*
* 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 @@ public class ThreadInfoCompositeData {
/*
* 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 @@ public class ThreadInfoCompositeData {
* 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 @@ public class ThreadInfoCompositeData {
/*
* 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 @@ public class ThreadInfoCompositeData {
/*
* 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 @@ public class ThreadInfoCompositeData {
}
}
@Test
public static void badNameCompositeData() throws Exception {
CompositeData cd = Factory.makeCompositeDataWithBadNames();
try {
@ -270,6 +275,7 @@ public class ThreadInfoCompositeData {
} catch (IllegalArgumentException e) { }
}
@Test
public static void badTypeCompositeData() throws Exception {
CompositeData cd = Factory.makeCompositeDataWithBadTypes();
@ -300,7 +306,7 @@ public class ThreadInfoCompositeData {
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;