8212795: ThreadInfoCompositeData.toCompositeData fails to map ThreadInfo to CompositeData
Reviewed-by: dfuchs
This commit is contained in:
parent
85598bc90f
commit
d523a17e80
@ -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.
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user