mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-22 20:14:43 +02:00
8198253: ThreadInfo.from(CompositeData) incorrectly accepts CompositeData with missing JDK 6 attributes
Reviewed-by: dfuchs, jmanson
This commit is contained in:
parent
dc42a2bab5
commit
3414903aba
9 changed files with 1075 additions and 794 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -116,11 +116,10 @@ public class MonitorInfo extends LockInfo {
|
|||
* <tbody style="text-align:left">
|
||||
* <tr>
|
||||
* <th scope="row">lockedStackFrame</th>
|
||||
* <td><code>CompositeData as specified in the
|
||||
* <a href="ThreadInfo.html#StackTrace">stackTrace</a>
|
||||
* attribute defined in the {@link ThreadInfo#from
|
||||
* ThreadInfo.from} method.
|
||||
* </code></td>
|
||||
* <td><a href="ThreadInfo.html#stackTraceElement">
|
||||
* {@code CompositeData} for {@code StackTraceElement}</a> as specified
|
||||
* in {@link ThreadInfo#from(CompositeData)} method.
|
||||
* </td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <th scope="row">lockedStackDepth</th>
|
||||
|
@ -134,7 +133,7 @@ public class MonitorInfo extends LockInfo {
|
|||
* @throws IllegalArgumentException if {@code cd} does not
|
||||
* represent a {@code MonitorInfo} with the attributes described
|
||||
* above.
|
||||
|
||||
*
|
||||
* @return a {@code MonitorInfo} object represented
|
||||
* by {@code cd} if {@code cd} is not {@code null};
|
||||
* {@code null} otherwise.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
package java.lang.management;
|
||||
|
||||
import javax.management.openmbean.ArrayType;
|
||||
import javax.management.openmbean.CompositeData;
|
||||
import sun.management.ManagementFactoryHelper;
|
||||
import sun.management.ThreadInfoCompositeData;
|
||||
|
@ -110,7 +111,6 @@ public class ThreadInfo {
|
|||
private StackTraceElement[] stackTrace;
|
||||
private MonitorInfo[] lockedMonitors;
|
||||
private LockInfo[] lockedSynchronizers;
|
||||
|
||||
private static MonitorInfo[] EMPTY_MONITORS = new MonitorInfo[0];
|
||||
private static LockInfo[] EMPTY_SYNCS = new LockInfo[0];
|
||||
|
||||
|
@ -264,6 +264,11 @@ public class ThreadInfo {
|
|||
/*
|
||||
* Constructs a {@code ThreadInfo} object from a
|
||||
* {@link CompositeData CompositeData}.
|
||||
*
|
||||
* @throws IllegalArgumentException if the given CompositeData does not
|
||||
* contain all of the attributes defined for ThreadInfo of version <= N.
|
||||
*
|
||||
* @see ThreadInfo#from
|
||||
*/
|
||||
private ThreadInfo(CompositeData cd) {
|
||||
ThreadInfoCompositeData ticd = ThreadInfoCompositeData.getInstance(cd);
|
||||
|
@ -281,41 +286,11 @@ public class ThreadInfo {
|
|||
suspended = ticd.suspended();
|
||||
inNative = ticd.inNative();
|
||||
stackTrace = ticd.stackTrace();
|
||||
|
||||
// 6.0 attributes
|
||||
if (ticd.hasV6()) {
|
||||
lock = ticd.lockInfo();
|
||||
lockedMonitors = ticd.lockedMonitors();
|
||||
lockedSynchronizers = ticd.lockedSynchronizers();
|
||||
} else {
|
||||
// lockInfo is a new attribute added in 1.6 ThreadInfo
|
||||
// If cd is a 5.0 version, construct the LockInfo object
|
||||
// from the lockName value.
|
||||
if (lockName != null) {
|
||||
String result[] = lockName.split("@");
|
||||
if (result.length == 2) {
|
||||
int identityHashCode = Integer.parseInt(result[1], 16);
|
||||
lock = new LockInfo(result[0], identityHashCode);
|
||||
} else {
|
||||
assert result.length == 2;
|
||||
lock = null;
|
||||
}
|
||||
} else {
|
||||
lock = null;
|
||||
}
|
||||
lockedMonitors = EMPTY_MONITORS;
|
||||
lockedSynchronizers = EMPTY_SYNCS;
|
||||
}
|
||||
|
||||
// 9.0 attributes
|
||||
if (ticd.isCurrentVersion()) {
|
||||
daemon = ticd.isDaemon();
|
||||
priority = ticd.getPriority();
|
||||
} else {
|
||||
// Not ideal, but unclear what else we can do.
|
||||
daemon = false;
|
||||
priority = Thread.NORM_PRIORITY;
|
||||
}
|
||||
lock = ticd.lockInfo();
|
||||
lockedMonitors = ticd.lockedMonitors();
|
||||
lockedSynchronizers = ticd.lockedSynchronizers();
|
||||
daemon = ticd.isDaemon();
|
||||
priority = ticd.getPriority();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -692,52 +667,105 @@ public class ThreadInfo {
|
|||
/**
|
||||
* Returns a {@code ThreadInfo} object represented by the
|
||||
* given {@code CompositeData}.
|
||||
* The given {@code CompositeData} must contain the following attributes
|
||||
* unless otherwise specified below:
|
||||
*
|
||||
* <a id="attributes"></a>
|
||||
* A {@code CompositeData} representing a {@code ThreadInfo} of
|
||||
* version <em>N</em> must contain all of the attributes defined
|
||||
* in version ≤ <em>N</em> unless specified otherwise.
|
||||
* The same rule applies the composite type of the given
|
||||
* {@code CompositeData} and transitively to attributes whose
|
||||
* {@linkplain CompositeData#getCompositeType() type} or
|
||||
* {@linkplain ArrayType#getElementOpenType() component type} is
|
||||
* {@code CompositeType}.
|
||||
* <p>
|
||||
* A {@code CompositeData} representing {@code ThreadInfo} of
|
||||
* version <em>N</em> contains {@code "stackTrace"} attribute and
|
||||
* {@code "lockedMonitors"} attribute representing
|
||||
* an array of {@code StackTraceElement} and
|
||||
* an array of {@link MonitorInfo} respectively
|
||||
* and their types are of version <em>N</em>.
|
||||
* The {@code "lockedStackFrame"} attribute in
|
||||
* {@link MonitorInfo#from(CompositeData) MonitorInfo}'s composite type
|
||||
* must represent {@code StackTraceElement} of the same version <em>N</em>.
|
||||
* Otherwise, this method will throw {@code IllegalArgumentException}.
|
||||
*
|
||||
* <table class="striped" style="margin-left:2em">
|
||||
* <caption style="display:none">The attributes and their types the given CompositeData contains</caption>
|
||||
* <caption style="display:none">The attributes and their types for ThreadInfo's composite data</caption>
|
||||
* <thead>
|
||||
* <tr>
|
||||
* <th scope="col">Attribute Name</th>
|
||||
* <th scope="col">Type</th>
|
||||
* <th scope="col">Since</th>
|
||||
* </tr>
|
||||
* </thead>
|
||||
* <tbody style="text-align:left">
|
||||
* <tr>
|
||||
* <th scope="row">threadId</th>
|
||||
* <td>{@code java.lang.Long}</td>
|
||||
* <td>5</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <th scope="row">threadName</th>
|
||||
* <td>{@code java.lang.String}</td>
|
||||
* <td>5</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <th scope="row">threadState</th>
|
||||
* <td>{@code java.lang.String}</td>
|
||||
* <td>5</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <th scope="row">suspended</th>
|
||||
* <td>{@code java.lang.Boolean}</td>
|
||||
* <td>5</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <th scope="row">inNative</th>
|
||||
* <td>{@code java.lang.Boolean}</td>
|
||||
* <td>5</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <th scope="row">blockedCount</th>
|
||||
* <td>{@code java.lang.Long}</td>
|
||||
* <td>5</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <th scope="row">blockedTime</th>
|
||||
* <td>{@code java.lang.Long}</td>
|
||||
* <td>5</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <th scope="row">waitedCount</th>
|
||||
* <td>{@code java.lang.Long}</td>
|
||||
* <td>5</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <th scope="row">waitedTime</th>
|
||||
* <td>{@code java.lang.Long}</td>
|
||||
* <td>5</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <th scope="row">lockName</th>
|
||||
* <td>{@code java.lang.String}</td>
|
||||
* <td>5</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <th scope="row">lockOwnerId</th>
|
||||
* <td>{@code java.lang.Long}</td>
|
||||
* <td>5</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <th scope="row">lockOwnerName</th>
|
||||
* <td>{@code java.lang.String}</td>
|
||||
* <td>5</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <th scope="row"><a id="StackTrace">stackTrace</a></th>
|
||||
* <td>{@code javax.management.openmbean.CompositeData[]}, each element
|
||||
* is a {@code CompositeData} representing {@code StackTraceElement}
|
||||
* as specified <a href="#stackTraceElement">below</a>.
|
||||
* </td>
|
||||
* <td>5</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <th scope="row">lockInfo</th>
|
||||
|
@ -745,78 +773,21 @@ public class ThreadInfo {
|
|||
* - the mapped type for {@link LockInfo} as specified in the
|
||||
* {@link LockInfo#from} method.
|
||||
* <p>
|
||||
* If {@code cd} does not contain this attribute,
|
||||
* If the given {@code CompositeData} does not contain this attribute,
|
||||
* the {@code LockInfo} object will be constructed from
|
||||
* the value of the {@code lockName} attribute. </td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <th scope="row">lockName</th>
|
||||
* <td>{@code java.lang.String}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <th scope="row">lockOwnerId</th>
|
||||
* <td>{@code java.lang.Long}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <th scope="row">lockOwnerName</th>
|
||||
* <td>{@code java.lang.String}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <th scope="row"><a id="StackTrace">stackTrace</a></th>
|
||||
* <td>{@code javax.management.openmbean.CompositeData[]}
|
||||
* <p>
|
||||
* Each element is a {@code CompositeData} representing
|
||||
* StackTraceElement containing the following attributes:
|
||||
* <table class="striped" style="margin-left:2em">
|
||||
* <caption style="display:none">The attributes and their types the given CompositeData contains</caption>
|
||||
* <thead style="text-align:center">
|
||||
* <tr>
|
||||
* <th scope="col">Attribute Name</th>
|
||||
* <th scope="col">Type</th>
|
||||
* </tr>
|
||||
* </thead>
|
||||
* <tbody style="text-align:left">
|
||||
* <tr>
|
||||
* <th scope="row">moduleName</th>
|
||||
* <td>{@code java.lang.String}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <th scope="row">moduleVersion</th>
|
||||
* <td>{@code java.lang.String}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <th scope="row">className</th>
|
||||
* <td>{@code java.lang.String}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <th scope="row">methodName</th>
|
||||
* <td>{@code java.lang.String}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <th scope="row">fileName</th>
|
||||
* <td>{@code java.lang.String}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <th scope="row">lineNumber</th>
|
||||
* <td>{@code java.lang.Integer}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <th scope="row">nativeMethod</th>
|
||||
* <td>{@code java.lang.Boolean}</td>
|
||||
* </tr>
|
||||
* </tbody>
|
||||
* </table>
|
||||
* </td>
|
||||
* the value of the {@code lockName} attribute.</td>
|
||||
* <td>6</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <th scope="row">lockedMonitors</th>
|
||||
* <td>{@code javax.management.openmbean.CompositeData[]}
|
||||
* whose element type is the mapped type for
|
||||
* {@link MonitorInfo} as specified in the
|
||||
* {@link MonitorInfo#from Monitor.from} method.
|
||||
* {@link MonitorInfo#from MonitorInfo.from} method.
|
||||
* <p>
|
||||
* If {@code cd} does not contain this attribute,
|
||||
* this attribute will be set to an empty array. </td>
|
||||
* If the given {@code CompositeData} does not contain this attribute,
|
||||
* this attribute will be set to an empty array.</td>
|
||||
* <td>6</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <th scope="row">lockedSynchronizers</th>
|
||||
|
@ -824,25 +795,93 @@ public class ThreadInfo {
|
|||
* whose element type is the mapped type for
|
||||
* {@link LockInfo} as specified in the {@link LockInfo#from} method.
|
||||
* <p>
|
||||
* If {@code cd} does not contain this attribute,
|
||||
* this attribute will be set to an empty array. </td>
|
||||
* If the given {@code CompositeData} does not contain this attribute,
|
||||
* this attribute will be set to an empty array.</td>
|
||||
* <td>6</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <th scope="row">daemon</th>
|
||||
* <td>{@code java.lang.Boolean}</td>
|
||||
* <td>{@code java.lang.Boolean}
|
||||
* <p>
|
||||
* If the given {@code CompositeData} does not contain this attribute,
|
||||
* this attribute will be set to {@code false}.</td>
|
||||
* <td>9</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <th scope="row">priority</th>
|
||||
* <td>{@code java.lang.Integer}
|
||||
* <p>
|
||||
* If the given {@code CompositeData} does not contain this attribute,
|
||||
* This attribute will be set to {@link Thread#NORM_PRIORITY}.</td>
|
||||
* <td>9</td>
|
||||
* </tr>
|
||||
* </tbody>
|
||||
* </table>
|
||||
*
|
||||
* <a id="stackTraceElement">A {@code CompositeData} representing
|
||||
* {@code StackTraceElement}</a> of version <em>N</em> must contain
|
||||
* all of the attributes defined in version ≤ <em>N</em>
|
||||
* unless specified otherwise.
|
||||
*
|
||||
* <table class="striped" style="margin-left:2em">
|
||||
* <caption style="display:none">The attributes and their types for StackTraceElement's composite data</caption>
|
||||
* <thead style="text-align:center">
|
||||
* <tr>
|
||||
* <th scope="col">Attribute Name</th>
|
||||
* <th scope="col">Type</th>
|
||||
* <th scope="col">Since</th>
|
||||
* </tr>
|
||||
* </thead>
|
||||
* <tbody style="text-align:left">
|
||||
* <tr>
|
||||
* <th scope="row">classLoaderName</th>
|
||||
* <td>{@code java.lang.String}</td>
|
||||
* <td>9</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <th scope="row">moduleName</th>
|
||||
* <td>{@code java.lang.String}</td>
|
||||
* <td>9</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <th scope="row">moduleVersion</th>
|
||||
* <td>{@code java.lang.String}</td>
|
||||
* <td>9</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <th scope="row">className</th>
|
||||
* <td>{@code java.lang.String}</td>
|
||||
* <td>5</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <th scope="row">methodName</th>
|
||||
* <td>{@code java.lang.String}</td>
|
||||
* <td>5</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <th scope="row">fileName</th>
|
||||
* <td>{@code java.lang.String}</td>
|
||||
* <td>5</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <th scope="row">lineNumber</th>
|
||||
* <td>{@code java.lang.Integer}</td>
|
||||
* <td>5</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <th scope="row">nativeMethod</th>
|
||||
* <td>{@code java.lang.Boolean}</td>
|
||||
* <td>5</td>
|
||||
* </tr>
|
||||
* </tbody>
|
||||
* </table>
|
||||
*
|
||||
* @param cd {@code CompositeData} representing a {@code ThreadInfo}
|
||||
*
|
||||
* @throws IllegalArgumentException if {@code cd} does not
|
||||
* represent a {@code ThreadInfo} with the attributes described
|
||||
* above.
|
||||
* @throws IllegalArgumentException if the given {@code cd} and
|
||||
* its composite type does not contain all of
|
||||
* <a href="#attributes">the attributes</a> defined for a
|
||||
* {@code ThreadInfo} of a specific runtime version.
|
||||
*
|
||||
* @return a {@code ThreadInfo} object represented
|
||||
* by {@code cd} if {@code cd} is not {@code null};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -58,15 +58,15 @@ public class LockInfoCompositeData extends LazyCompositeData {
|
|||
|
||||
protected CompositeData getCompositeData() {
|
||||
// CONTENTS OF THIS ARRAY MUST BE SYNCHRONIZED WITH
|
||||
// lockInfoItemNames!
|
||||
// LOCK_INFO_ATTRIBUTES!
|
||||
final Object[] lockInfoItemValues = {
|
||||
new String(lock.getClassName()),
|
||||
lock.getIdentityHashCode(),
|
||||
};
|
||||
|
||||
try {
|
||||
return new CompositeDataSupport(lockInfoCompositeType,
|
||||
lockInfoItemNames,
|
||||
return new CompositeDataSupport(LOCK_INFO_COMPOSITE_TYPE,
|
||||
LOCK_INFO_ATTRIBUTES,
|
||||
lockInfoItemValues);
|
||||
} catch (OpenDataException e) {
|
||||
// Should never reach here
|
||||
|
@ -74,10 +74,10 @@ public class LockInfoCompositeData extends LazyCompositeData {
|
|||
}
|
||||
}
|
||||
|
||||
private static final CompositeType lockInfoCompositeType;
|
||||
private static final CompositeType LOCK_INFO_COMPOSITE_TYPE;
|
||||
static {
|
||||
try {
|
||||
lockInfoCompositeType = (CompositeType)
|
||||
LOCK_INFO_COMPOSITE_TYPE = (CompositeType)
|
||||
MappedMXBeanType.toOpenType(LockInfo.class);
|
||||
} catch (OpenDataException e) {
|
||||
// Should never reach here
|
||||
|
@ -85,13 +85,13 @@ public class LockInfoCompositeData extends LazyCompositeData {
|
|||
}
|
||||
}
|
||||
|
||||
static CompositeType getLockInfoCompositeType() {
|
||||
return lockInfoCompositeType;
|
||||
static CompositeType compositeType() {
|
||||
return LOCK_INFO_COMPOSITE_TYPE;
|
||||
}
|
||||
|
||||
private static final String CLASS_NAME = "className";
|
||||
private static final String IDENTITY_HASH_CODE = "identityHashCode";
|
||||
private static final String[] lockInfoItemNames = {
|
||||
private static final String[] LOCK_INFO_ATTRIBUTES = {
|
||||
CLASS_NAME,
|
||||
IDENTITY_HASH_CODE,
|
||||
};
|
||||
|
@ -104,7 +104,7 @@ public class LockInfoCompositeData extends LazyCompositeData {
|
|||
throw new NullPointerException("Null CompositeData");
|
||||
}
|
||||
|
||||
if (!isTypeMatched(lockInfoCompositeType, cd.getCompositeType())) {
|
||||
if (!isTypeMatched(LOCK_INFO_COMPOSITE_TYPE, cd.getCompositeType())) {
|
||||
throw new IllegalArgumentException(
|
||||
"Unexpected composite type for LockInfo");
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -30,7 +30,7 @@ import javax.management.openmbean.CompositeType;
|
|||
import javax.management.openmbean.CompositeData;
|
||||
import javax.management.openmbean.CompositeDataSupport;
|
||||
import javax.management.openmbean.OpenDataException;
|
||||
import java.util.Set;
|
||||
import javax.management.openmbean.OpenType;
|
||||
|
||||
/**
|
||||
* A CompositeData for MonitorInfo for the local management support.
|
||||
|
@ -55,14 +55,14 @@ public class MonitorInfoCompositeData extends LazyCompositeData {
|
|||
|
||||
protected CompositeData getCompositeData() {
|
||||
// CONTENTS OF THIS ARRAY MUST BE SYNCHRONIZED WITH
|
||||
// monitorInfoItemNames!
|
||||
// MONITOR_INFO_ATTRIBUTES!
|
||||
|
||||
int len = monitorInfoItemNames.length;
|
||||
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 = monitorInfoItemNames[i];
|
||||
String item = MONITOR_INFO_ATTRIBUTES[i];
|
||||
if (item.equals(LOCKED_STACK_FRAME)) {
|
||||
StackTraceElement ste = lock.getLockedStackFrame();
|
||||
values[i] = (ste != null ? StackTraceElementCompositeData.
|
||||
|
@ -76,8 +76,8 @@ public class MonitorInfoCompositeData extends LazyCompositeData {
|
|||
}
|
||||
|
||||
try {
|
||||
return new CompositeDataSupport(monitorInfoCompositeType,
|
||||
monitorInfoItemNames,
|
||||
return new CompositeDataSupport(MONITOR_INFO_COMPOSITE_TYPE,
|
||||
MONITOR_INFO_ATTRIBUTES,
|
||||
values);
|
||||
} catch (OpenDataException e) {
|
||||
// Should never reach here
|
||||
|
@ -85,28 +85,50 @@ public class MonitorInfoCompositeData extends LazyCompositeData {
|
|||
}
|
||||
}
|
||||
|
||||
private static final CompositeType monitorInfoCompositeType;
|
||||
private static final String[] monitorInfoItemNames;
|
||||
private static final String CLASS_NAME = "className";
|
||||
private static final String IDENTITY_HASH_CODE = "identityHashCode";
|
||||
private static final String LOCKED_STACK_FRAME = "lockedStackFrame";
|
||||
private static final String LOCKED_STACK_DEPTH = "lockedStackDepth";
|
||||
|
||||
private static final String[] MONITOR_INFO_ATTRIBUTES = {
|
||||
CLASS_NAME,
|
||||
IDENTITY_HASH_CODE,
|
||||
LOCKED_STACK_FRAME,
|
||||
LOCKED_STACK_DEPTH
|
||||
};
|
||||
|
||||
private static final CompositeType MONITOR_INFO_COMPOSITE_TYPE;
|
||||
private static final CompositeType V6_COMPOSITE_TYPE;
|
||||
static {
|
||||
try {
|
||||
monitorInfoCompositeType = (CompositeType)
|
||||
MONITOR_INFO_COMPOSITE_TYPE = (CompositeType)
|
||||
MappedMXBeanType.toOpenType(MonitorInfo.class);
|
||||
Set<String> s = monitorInfoCompositeType.keySet();
|
||||
monitorInfoItemNames = s.toArray(new String[0]);
|
||||
|
||||
OpenType<?>[] types = new OpenType<?>[MONITOR_INFO_ATTRIBUTES.length];
|
||||
for (int i = 0; i < MONITOR_INFO_ATTRIBUTES.length; i++) {
|
||||
String name = MONITOR_INFO_ATTRIBUTES[i];
|
||||
types[i] = name.equals(LOCKED_STACK_FRAME)
|
||||
? StackTraceElementCompositeData.v5CompositeType()
|
||||
: MONITOR_INFO_COMPOSITE_TYPE.getType(name);
|
||||
}
|
||||
V6_COMPOSITE_TYPE = new CompositeType("MonitorInfo",
|
||||
"JDK 6 MonitorInfo",
|
||||
MONITOR_INFO_ATTRIBUTES,
|
||||
MONITOR_INFO_ATTRIBUTES,
|
||||
types);
|
||||
} catch (OpenDataException e) {
|
||||
// Should never reach here
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
static CompositeType getMonitorInfoCompositeType() {
|
||||
return monitorInfoCompositeType;
|
||||
static CompositeType v6CompositeType() {
|
||||
return V6_COMPOSITE_TYPE;
|
||||
}
|
||||
|
||||
private static final String CLASS_NAME = "className";
|
||||
private static final String IDENTITY_HASH_CODE = "identityHashCode";
|
||||
private static final String LOCKED_STACK_FRAME = "lockedStackFrame";
|
||||
private static final String LOCKED_STACK_DEPTH = "lockedStackDepth";
|
||||
static CompositeType compositeType() {
|
||||
return MONITOR_INFO_COMPOSITE_TYPE;
|
||||
}
|
||||
|
||||
public static String getClassName(CompositeData cd) {
|
||||
return getString(cd, CLASS_NAME);
|
||||
|
@ -138,7 +160,8 @@ public class MonitorInfoCompositeData extends LazyCompositeData {
|
|||
throw new NullPointerException("Null CompositeData");
|
||||
}
|
||||
|
||||
if (!isTypeMatched(monitorInfoCompositeType, cd.getCompositeType())) {
|
||||
if (!isTypeMatched(MONITOR_INFO_COMPOSITE_TYPE, cd.getCompositeType()) &&
|
||||
!isTypeMatched(V6_COMPOSITE_TYPE, cd.getCompositeType())) {
|
||||
throw new IllegalArgumentException(
|
||||
"Unexpected composite type for MonitorInfo");
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -25,13 +25,13 @@
|
|||
|
||||
package sun.management;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Predicate;
|
||||
import javax.management.openmbean.CompositeType;
|
||||
import javax.management.openmbean.CompositeData;
|
||||
import javax.management.openmbean.CompositeDataSupport;
|
||||
import javax.management.openmbean.OpenDataException;
|
||||
import javax.management.openmbean.OpenType;
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* A CompositeData for StackTraceElement for the local management support.
|
||||
|
@ -52,12 +52,7 @@ public class StackTraceElementCompositeData extends LazyCompositeData {
|
|||
public static StackTraceElement from(CompositeData cd) {
|
||||
validateCompositeData(cd);
|
||||
|
||||
if (stackTraceElementV6CompositeType.equals(cd.getCompositeType())) {
|
||||
return new StackTraceElement(getString(cd, CLASS_NAME),
|
||||
getString(cd, METHOD_NAME),
|
||||
getString(cd, FILE_NAME),
|
||||
getInt(cd, LINE_NUMBER));
|
||||
} else {
|
||||
if (STACK_TRACE_ELEMENT_COMPOSITE_TYPE.equals(cd.getCompositeType())) {
|
||||
return new StackTraceElement(getString(cd, CLASS_LOADER_NAME),
|
||||
getString(cd, MODULE_NAME),
|
||||
getString(cd, MODULE_VERSION),
|
||||
|
@ -65,6 +60,12 @@ public class StackTraceElementCompositeData extends LazyCompositeData {
|
|||
getString(cd, METHOD_NAME),
|
||||
getString(cd, FILE_NAME),
|
||||
getInt(cd, LINE_NUMBER));
|
||||
} else {
|
||||
return new StackTraceElement(getString(cd, CLASS_NAME),
|
||||
getString(cd, METHOD_NAME),
|
||||
getString(cd, FILE_NAME),
|
||||
getInt(cd, LINE_NUMBER));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -75,7 +76,7 @@ public class StackTraceElementCompositeData extends LazyCompositeData {
|
|||
|
||||
protected CompositeData getCompositeData() {
|
||||
// CONTENTS OF THIS ARRAY MUST BE SYNCHRONIZED WITH
|
||||
// stackTraceElementItemNames!
|
||||
// STACK_TRACE_ELEMENT_ATTRIBUTES!
|
||||
final Object[] stackTraceElementItemValues = {
|
||||
ste.getClassLoaderName(),
|
||||
ste.getModuleName(),
|
||||
|
@ -87,8 +88,8 @@ public class StackTraceElementCompositeData extends LazyCompositeData {
|
|||
ste.isNativeMethod(),
|
||||
};
|
||||
try {
|
||||
return new CompositeDataSupport(stackTraceElementCompositeType,
|
||||
stackTraceElementItemNames,
|
||||
return new CompositeDataSupport(STACK_TRACE_ELEMENT_COMPOSITE_TYPE,
|
||||
STACK_TRACE_ELEMENT_ATTRIBUTES,
|
||||
stackTraceElementItemValues);
|
||||
} catch (OpenDataException e) {
|
||||
// Should never reach here
|
||||
|
@ -106,11 +107,7 @@ public class StackTraceElementCompositeData extends LazyCompositeData {
|
|||
private static final String LINE_NUMBER = "lineNumber";
|
||||
private static final String NATIVE_METHOD = "nativeMethod";
|
||||
|
||||
|
||||
private static final String[] stackTraceElementItemNames = {
|
||||
CLASS_LOADER_NAME,
|
||||
MODULE_NAME,
|
||||
MODULE_VERSION,
|
||||
private static final String[] V5_ATTRIBUTES = {
|
||||
CLASS_NAME,
|
||||
METHOD_NAME,
|
||||
FILE_NAME,
|
||||
|
@ -118,30 +115,48 @@ public class StackTraceElementCompositeData extends LazyCompositeData {
|
|||
NATIVE_METHOD,
|
||||
};
|
||||
|
||||
private static final String[] stackTraceElementV9ItemNames = {
|
||||
private static final String[] V9_ATTRIBUTES = {
|
||||
CLASS_LOADER_NAME,
|
||||
MODULE_NAME,
|
||||
MODULE_VERSION,
|
||||
};
|
||||
|
||||
private static final CompositeType stackTraceElementCompositeType;
|
||||
private static final CompositeType stackTraceElementV6CompositeType;
|
||||
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 {
|
||||
try {
|
||||
stackTraceElementCompositeType = (CompositeType)
|
||||
STACK_TRACE_ELEMENT_COMPOSITE_TYPE = (CompositeType)
|
||||
MappedMXBeanType.toOpenType(StackTraceElement.class);
|
||||
stackTraceElementV6CompositeType =
|
||||
TypeVersionMapper.getInstance().getVersionedCompositeType(
|
||||
stackTraceElementCompositeType,
|
||||
TypeVersionMapper.V6
|
||||
);
|
||||
|
||||
OpenType<?>[] types = new OpenType<?>[V5_ATTRIBUTES.length];
|
||||
for (int i=0; i < V5_ATTRIBUTES.length; i++) {
|
||||
String name = V5_ATTRIBUTES[i];
|
||||
types[i] = STACK_TRACE_ELEMENT_COMPOSITE_TYPE.getType(name);
|
||||
}
|
||||
V5_COMPOSITE_TYPE = new CompositeType("StackTraceElement",
|
||||
"JDK 5 StackTraceElement",
|
||||
V5_ATTRIBUTES,
|
||||
V5_ATTRIBUTES,
|
||||
types);
|
||||
} catch (OpenDataException e) {
|
||||
// Should never reach here
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
/** Validate if the input CompositeData has the expected
|
||||
static CompositeType v5CompositeType() {
|
||||
return V5_COMPOSITE_TYPE;
|
||||
}
|
||||
static CompositeType compositeType() {
|
||||
return STACK_TRACE_ELEMENT_COMPOSITE_TYPE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate if the input CompositeData has the expected
|
||||
* CompositeType (i.e. contain all attributes with expected
|
||||
* names and types).
|
||||
*/
|
||||
|
@ -151,22 +166,11 @@ public class StackTraceElementCompositeData extends LazyCompositeData {
|
|||
}
|
||||
|
||||
CompositeType ct = cd.getCompositeType();
|
||||
if (!isTypeMatched(stackTraceElementCompositeType, ct)) {
|
||||
if (!isTypeMatched(stackTraceElementV6CompositeType, ct)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Unexpected composite type for StackTraceElement");
|
||||
}
|
||||
if (!isTypeMatched(STACK_TRACE_ELEMENT_COMPOSITE_TYPE, ct) &&
|
||||
!isTypeMatched(V5_COMPOSITE_TYPE, ct)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Unexpected composite type for StackTraceElement");
|
||||
}
|
||||
}
|
||||
|
||||
static boolean isV6Attribute(String name) {
|
||||
for(String attrName : stackTraceElementV9ItemNames) {
|
||||
if (name.equals(attrName)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = -2704607706598396827L;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -28,10 +28,16 @@ package sun.management;
|
|||
import java.lang.management.ThreadInfo;
|
||||
import java.lang.management.MonitorInfo;
|
||||
import java.lang.management.LockInfo;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
import javax.management.openmbean.ArrayType;
|
||||
import javax.management.openmbean.CompositeType;
|
||||
import javax.management.openmbean.CompositeData;
|
||||
import javax.management.openmbean.CompositeDataSupport;
|
||||
import javax.management.openmbean.OpenDataException;
|
||||
import javax.management.openmbean.OpenType;
|
||||
|
||||
/**
|
||||
* A CompositeData for ThreadInfo for the local management support.
|
||||
|
@ -41,35 +47,21 @@ import javax.management.openmbean.OpenDataException;
|
|||
public class ThreadInfoCompositeData extends LazyCompositeData {
|
||||
private final ThreadInfo threadInfo;
|
||||
private final CompositeData cdata;
|
||||
private final boolean currentVersion;
|
||||
private final boolean hasV6;
|
||||
|
||||
private ThreadInfoCompositeData(ThreadInfo ti) {
|
||||
this.threadInfo = ti;
|
||||
this.currentVersion = true;
|
||||
this.cdata = null;
|
||||
this.hasV6 = true;
|
||||
}
|
||||
|
||||
private ThreadInfoCompositeData(CompositeData cd) {
|
||||
this.threadInfo = null;
|
||||
this.currentVersion = ThreadInfoCompositeData.isCurrentVersion(cd);
|
||||
this.cdata = cd;
|
||||
this.hasV6 = ThreadInfoCompositeData.hasV6(cd);
|
||||
}
|
||||
|
||||
public ThreadInfo getThreadInfo() {
|
||||
return threadInfo;
|
||||
}
|
||||
|
||||
public boolean hasV6() {
|
||||
return hasV6;
|
||||
}
|
||||
|
||||
public boolean isCurrentVersion() {
|
||||
return currentVersion;
|
||||
}
|
||||
|
||||
public static ThreadInfoCompositeData getInstance(CompositeData cd) {
|
||||
validateCompositeData(cd);
|
||||
return new ThreadInfoCompositeData(cd);
|
||||
|
@ -112,7 +104,7 @@ public class ThreadInfoCompositeData extends LazyCompositeData {
|
|||
}
|
||||
|
||||
// CONTENTS OF THIS ARRAY MUST BE SYNCHRONIZED WITH
|
||||
// threadInfoItemNames!
|
||||
// THREAD_INFO_ATTRIBUTES!
|
||||
final Object[] threadInfoItemValues = {
|
||||
threadInfo.getThreadId(),
|
||||
threadInfo.getThreadName(),
|
||||
|
@ -126,8 +118,8 @@ public class ThreadInfoCompositeData extends LazyCompositeData {
|
|||
threadInfo.getLockOwnerId(),
|
||||
threadInfo.getLockOwnerName(),
|
||||
stackTraceData,
|
||||
threadInfo.isSuspended(),
|
||||
threadInfo.isInNative(),
|
||||
threadInfo.isSuspended(),
|
||||
threadInfo.isInNative(),
|
||||
lockedMonitorsData,
|
||||
lockedSyncsData,
|
||||
threadInfo.isDaemon(),
|
||||
|
@ -135,8 +127,8 @@ public class ThreadInfoCompositeData extends LazyCompositeData {
|
|||
};
|
||||
|
||||
try {
|
||||
return new CompositeDataSupport(threadInfoCompositeType,
|
||||
threadInfoItemNames,
|
||||
return new CompositeDataSupport(compositeType(),
|
||||
THREAD_INFO_ATTRIBTUES,
|
||||
threadInfoItemValues);
|
||||
} catch (OpenDataException e) {
|
||||
// Should never reach here
|
||||
|
@ -164,7 +156,7 @@ public class ThreadInfoCompositeData extends LazyCompositeData {
|
|||
private static final String LOCKED_MONITORS = "lockedMonitors";
|
||||
private static final String LOCKED_SYNCS = "lockedSynchronizers";
|
||||
|
||||
private static final String[] threadInfoItemNames = {
|
||||
private static final String[] V5_ATTRIBUTES = {
|
||||
THREAD_ID,
|
||||
THREAD_NAME,
|
||||
THREAD_STATE,
|
||||
|
@ -172,109 +164,28 @@ public class ThreadInfoCompositeData extends LazyCompositeData {
|
|||
BLOCKED_COUNT,
|
||||
WAITED_TIME,
|
||||
WAITED_COUNT,
|
||||
LOCK_INFO,
|
||||
LOCK_NAME,
|
||||
LOCK_OWNER_ID,
|
||||
LOCK_OWNER_NAME,
|
||||
STACK_TRACE,
|
||||
SUSPENDED,
|
||||
IN_NATIVE,
|
||||
LOCKED_MONITORS,
|
||||
LOCKED_SYNCS,
|
||||
DAEMON,
|
||||
PRIORITY,
|
||||
IN_NATIVE
|
||||
};
|
||||
|
||||
// New attributes added in 6.0 ThreadInfo
|
||||
private static final String[] threadInfoV6Attributes = {
|
||||
private static final String[] V6_ATTRIBUTES = {
|
||||
LOCK_INFO,
|
||||
LOCKED_MONITORS,
|
||||
LOCKED_SYNCS,
|
||||
};
|
||||
|
||||
private static final String[] threadInfoV9Attributes = {
|
||||
private static final String[] V9_ATTRIBUTES = {
|
||||
DAEMON,
|
||||
PRIORITY,
|
||||
};
|
||||
|
||||
// Current version of ThreadInfo
|
||||
private static final CompositeType threadInfoCompositeType;
|
||||
// Previous version of ThreadInfo
|
||||
private static final CompositeType threadInfoV6CompositeType;
|
||||
// Previous-previous version of ThreadInfo
|
||||
private static final CompositeType threadInfoV5CompositeType;
|
||||
private static final CompositeType lockInfoCompositeType;
|
||||
static {
|
||||
try {
|
||||
threadInfoCompositeType = (CompositeType)
|
||||
MappedMXBeanType.toOpenType(ThreadInfo.class);
|
||||
// Form a CompositeType for JDK 5.0 ThreadInfo version
|
||||
|
||||
threadInfoV5CompositeType =
|
||||
TypeVersionMapper.getInstance().getVersionedCompositeType(
|
||||
threadInfoCompositeType, TypeVersionMapper.V5
|
||||
);
|
||||
|
||||
threadInfoV6CompositeType =
|
||||
TypeVersionMapper.getInstance().getVersionedCompositeType(
|
||||
threadInfoCompositeType, TypeVersionMapper.V6
|
||||
);
|
||||
} catch (OpenDataException e) {
|
||||
// Should never reach here
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
|
||||
// Each CompositeData object has its CompositeType associated
|
||||
// with it. So we can get the CompositeType representing LockInfo
|
||||
// from a mapped CompositeData for any LockInfo object.
|
||||
// Thus we construct a random LockInfo object and pass it
|
||||
// to LockInfoCompositeData to do the conversion.
|
||||
Object o = new Object();
|
||||
LockInfo li = new LockInfo(o.getClass().getName(),
|
||||
System.identityHashCode(o));
|
||||
CompositeData cd = LockInfoCompositeData.toCompositeData(li);
|
||||
lockInfoCompositeType = cd.getCompositeType();
|
||||
}
|
||||
|
||||
static boolean isV5Attribute(String itemName) {
|
||||
for (String n : threadInfoV6Attributes) {
|
||||
if (itemName.equals(n)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (String n : threadInfoV9Attributes) {
|
||||
if (itemName.equals(n)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static boolean isV6Attribute(String itemName) {
|
||||
for (String n : threadInfoV9Attributes) {
|
||||
if (itemName.equals(n)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean isCurrentVersion(CompositeData cd) {
|
||||
if (cd == null) {
|
||||
throw new NullPointerException("Null CompositeData");
|
||||
}
|
||||
|
||||
return isTypeMatched(threadInfoCompositeType, cd.getCompositeType());
|
||||
}
|
||||
|
||||
private static boolean hasV6(CompositeData cd) {
|
||||
if (cd == null) {
|
||||
throw new NullPointerException("Null CompositeData");
|
||||
}
|
||||
|
||||
return isTypeMatched(threadInfoCompositeType, cd.getCompositeType()) ||
|
||||
isTypeMatched(threadInfoV6CompositeType, cd.getCompositeType());
|
||||
}
|
||||
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);
|
||||
|
@ -333,12 +244,18 @@ public class ThreadInfoCompositeData extends LazyCompositeData {
|
|||
return getBoolean(cdata, IN_NATIVE);
|
||||
}
|
||||
|
||||
/*
|
||||
* if daemon attribute is not present, default to false.
|
||||
*/
|
||||
public boolean isDaemon() {
|
||||
return getBoolean(cdata, DAEMON);
|
||||
return cdata.containsKey(DAEMON) ? getBoolean(cdata, DAEMON) : false;
|
||||
}
|
||||
|
||||
/*
|
||||
* if priority attribute is not present, default to norm priority.
|
||||
*/
|
||||
public int getPriority(){
|
||||
return getInt(cdata, PRIORITY);
|
||||
return cdata.containsKey(PRIORITY) ? getInt(cdata, PRIORITY) : Thread.NORM_PRIORITY;
|
||||
}
|
||||
|
||||
public StackTraceElement[] stackTrace() {
|
||||
|
@ -356,13 +273,37 @@ public class ThreadInfoCompositeData extends LazyCompositeData {
|
|||
return stackTrace;
|
||||
}
|
||||
|
||||
// 6.0 new attributes
|
||||
/*
|
||||
* lockInfo is a new attribute added in JDK 6 ThreadInfo
|
||||
* If cd is a 5.0 version, construct the LockInfo object
|
||||
* from the lockName value.
|
||||
*/
|
||||
public LockInfo lockInfo() {
|
||||
CompositeData lockInfoData = (CompositeData) cdata.get(LOCK_INFO);
|
||||
return LockInfo.from(lockInfoData);
|
||||
if (cdata.containsKey(LOCK_INFO)) {
|
||||
CompositeData lockInfoData = (CompositeData) cdata.get(LOCK_INFO);
|
||||
return LockInfo.from(lockInfoData);
|
||||
} else {
|
||||
String lockName = lockName();
|
||||
LockInfo lock = null;
|
||||
if (lockName != null) {
|
||||
String result[] = lockName.split("@");
|
||||
if (result.length == 2) {
|
||||
int identityHashCode = Integer.parseInt(result[1], 16);
|
||||
lock = new LockInfo(result[0], identityHashCode);
|
||||
}
|
||||
}
|
||||
return lock;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an empty array if locked_monitors attribute is not present.
|
||||
*/
|
||||
public MonitorInfo[] lockedMonitors() {
|
||||
if (!cdata.containsKey(LOCKED_MONITORS)) {
|
||||
return new MonitorInfo[0];
|
||||
}
|
||||
|
||||
CompositeData[] lockedMonitorsData =
|
||||
(CompositeData[]) cdata.get(LOCKED_MONITORS);
|
||||
|
||||
|
@ -377,7 +318,14 @@ public class ThreadInfoCompositeData extends LazyCompositeData {
|
|||
return monitors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an empty array if locked_monitors attribute is not present.
|
||||
*/
|
||||
public LockInfo[] lockedSynchronizers() {
|
||||
if (!cdata.containsKey(LOCKED_SYNCS)) {
|
||||
return new LockInfo[0];
|
||||
}
|
||||
|
||||
CompositeData[] lockedSyncsData =
|
||||
(CompositeData[]) cdata.get(LOCKED_SYNCS);
|
||||
|
||||
|
@ -391,7 +339,8 @@ public class ThreadInfoCompositeData extends LazyCompositeData {
|
|||
return locks;
|
||||
}
|
||||
|
||||
/** Validate if the input CompositeData has the expected
|
||||
/**
|
||||
* Validate if the input CompositeData has the expected
|
||||
* CompositeType (i.e. contain all attributes with expected
|
||||
* names and types).
|
||||
*/
|
||||
|
@ -401,62 +350,98 @@ public class ThreadInfoCompositeData extends LazyCompositeData {
|
|||
}
|
||||
|
||||
CompositeType type = cd.getCompositeType();
|
||||
boolean currentVersion = true;
|
||||
if (!isTypeMatched(threadInfoCompositeType, type)) {
|
||||
currentVersion = false;
|
||||
// check if cd is an older version
|
||||
if (!isTypeMatched(threadInfoV5CompositeType, type) &&
|
||||
!isTypeMatched(threadInfoV6CompositeType, type)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Unexpected composite type for ThreadInfo");
|
||||
}
|
||||
int version;
|
||||
if (Arrays.stream(V9_ATTRIBUTES).anyMatch(type::containsKey)) {
|
||||
version = Runtime.version().feature();
|
||||
} else if (Arrays.stream(V6_ATTRIBUTES).anyMatch(type::containsKey)) {
|
||||
version = 6;
|
||||
} else {
|
||||
version = 5;
|
||||
}
|
||||
|
||||
CompositeData[] stackTraceData =
|
||||
(CompositeData[]) cd.get(STACK_TRACE);
|
||||
if (stackTraceData == null) {
|
||||
if (!isTypeMatched(ThreadInfoCompositeTypes.ofVersion(version), type)) {
|
||||
throw new IllegalArgumentException(
|
||||
"StackTraceElement[] is missing");
|
||||
}
|
||||
if (stackTraceData.length > 0) {
|
||||
StackTraceElementCompositeData.validateCompositeData(stackTraceData[0]);
|
||||
}
|
||||
|
||||
// validate v6 attributes
|
||||
if (currentVersion) {
|
||||
CompositeData li = (CompositeData) cd.get(LOCK_INFO);
|
||||
if (li != null) {
|
||||
if (!isTypeMatched(lockInfoCompositeType,
|
||||
li.getCompositeType())) {
|
||||
throw new IllegalArgumentException(
|
||||
"Unexpected composite type for \"" +
|
||||
LOCK_INFO + "\" attribute.");
|
||||
}
|
||||
}
|
||||
|
||||
CompositeData[] lms = (CompositeData[]) cd.get(LOCKED_MONITORS);
|
||||
if (lms == null) {
|
||||
throw new IllegalArgumentException("MonitorInfo[] is null");
|
||||
}
|
||||
if (lms.length > 0) {
|
||||
MonitorInfoCompositeData.validateCompositeData(lms[0]);
|
||||
}
|
||||
|
||||
CompositeData[] lsyncs = (CompositeData[]) cd.get(LOCKED_SYNCS);
|
||||
if (lsyncs == null) {
|
||||
throw new IllegalArgumentException("LockInfo[] is null");
|
||||
}
|
||||
if (lsyncs.length > 0) {
|
||||
if (!isTypeMatched(lockInfoCompositeType,
|
||||
lsyncs[0].getCompositeType())) {
|
||||
throw new IllegalArgumentException(
|
||||
"Unexpected composite type for \"" +
|
||||
LOCKED_SYNCS + "\" attribute.");
|
||||
}
|
||||
}
|
||||
|
||||
"Unexpected composite type for ThreadInfo of version " + version);
|
||||
}
|
||||
}
|
||||
|
||||
public static CompositeType compositeType() {
|
||||
return ThreadInfoCompositeTypes.compositeTypes.get(0);
|
||||
}
|
||||
|
||||
static class ThreadInfoCompositeTypes {
|
||||
static final int CURRENT = Runtime.version().feature();
|
||||
static final Map<Integer, CompositeType> compositeTypes = initCompositeTypes();
|
||||
/*
|
||||
* Returns CompositeType of the given runtime version
|
||||
*/
|
||||
static CompositeType ofVersion(int version) {
|
||||
return compositeTypes.get(version);
|
||||
}
|
||||
|
||||
static Map<Integer, CompositeType> initCompositeTypes() {
|
||||
Map<Integer, CompositeType> types = new HashMap<>();
|
||||
CompositeType ctype = initCompositeType();
|
||||
types.put(CURRENT, ctype);
|
||||
types.put(5, initV5CompositeType(ctype));
|
||||
types.put(6, initV6CompositeType(ctype));
|
||||
return types;
|
||||
}
|
||||
|
||||
static CompositeType initCompositeType() {
|
||||
try {
|
||||
return (CompositeType)MappedMXBeanType.toOpenType(ThreadInfo.class);
|
||||
} catch (OpenDataException e) {
|
||||
// Should never reach here
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
static CompositeType initV5CompositeType(CompositeType threadInfoCompositeType) {
|
||||
try {
|
||||
OpenType<?>[] v5Types = new OpenType<?>[V5_ATTRIBUTES.length];
|
||||
for (int i = 0; i < v5Types.length; i++) {
|
||||
String name = V5_ATTRIBUTES[i];
|
||||
v5Types[i] = name.equals(STACK_TRACE)
|
||||
? new ArrayType<>(1, StackTraceElementCompositeData.v5CompositeType())
|
||||
: threadInfoCompositeType.getType(name);
|
||||
}
|
||||
return new CompositeType("ThreadInfo",
|
||||
"JDK 5 ThreadInfo",
|
||||
V5_ATTRIBUTES,
|
||||
V5_ATTRIBUTES,
|
||||
v5Types);
|
||||
} catch (OpenDataException e) {
|
||||
// Should never reach here
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
static CompositeType initV6CompositeType(CompositeType threadInfoCompositeType) {
|
||||
try {
|
||||
String[] v6Names = Stream.of(V5_ATTRIBUTES, V6_ATTRIBUTES)
|
||||
.flatMap(Arrays::stream).toArray(String[]::new);
|
||||
OpenType<?>[] v6Types = new OpenType<?>[v6Names.length];
|
||||
for (int i = 0; i < v6Names.length; i++) {
|
||||
String name = v6Names[i];
|
||||
OpenType<?> ot = threadInfoCompositeType.getType(name);
|
||||
if (name.equals(STACK_TRACE)) {
|
||||
ot = new ArrayType<>(1, StackTraceElementCompositeData.v5CompositeType());
|
||||
} else if (name.equals(LOCKED_MONITORS)) {
|
||||
ot = new ArrayType<>(1, MonitorInfoCompositeData.v6CompositeType());
|
||||
}
|
||||
v6Types[i] = ot;
|
||||
}
|
||||
return new CompositeType("ThreadInfo",
|
||||
"JDK 6 ThreadInfo",
|
||||
v6Names,
|
||||
v6Names,
|
||||
v6Types);
|
||||
} catch (OpenDataException e) {
|
||||
// Should never reach here
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
private static final long serialVersionUID = 2464378539119753175L;
|
||||
}
|
||||
|
|
|
@ -1,174 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package sun.management;
|
||||
|
||||
import java.lang.management.ThreadInfo;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Predicate;
|
||||
import javax.management.openmbean.ArrayType;
|
||||
import javax.management.openmbean.CompositeType;
|
||||
import javax.management.openmbean.OpenDataException;
|
||||
import javax.management.openmbean.OpenType;
|
||||
import javax.management.openmbean.SimpleType;
|
||||
import javax.management.openmbean.TabularType;
|
||||
import static sun.management.Util.toStringArray;
|
||||
|
||||
/**
|
||||
* Provides simplistic support for versioning of {@linkplain CompositeType} instances
|
||||
* based on the latest version and filtering out certain items.
|
||||
*/
|
||||
final class TypeVersionMapper {
|
||||
private static final class Singleton {
|
||||
private final static TypeVersionMapper INSTANCE = new TypeVersionMapper();
|
||||
}
|
||||
|
||||
final static String V5 = "J2SE 5.0";
|
||||
final static String V6 = "Java SE 6";
|
||||
|
||||
private final Map<String, Map<String, Predicate<String>>> filterMap;
|
||||
|
||||
private TypeVersionMapper() {
|
||||
filterMap = new HashMap<>();
|
||||
setupStackTraceElement();
|
||||
setupThreadInfo();
|
||||
}
|
||||
|
||||
public static TypeVersionMapper getInstance() {
|
||||
return Singleton.INSTANCE;
|
||||
}
|
||||
|
||||
private void setupStackTraceElement() {
|
||||
Map<String, Predicate<String>> filter = new HashMap<>();
|
||||
filterMap.put(StackTraceElement.class.getName(), filter);
|
||||
filter.put(V5, StackTraceElementCompositeData::isV6Attribute);
|
||||
filter.put(V6, StackTraceElementCompositeData::isV6Attribute);
|
||||
}
|
||||
|
||||
private void setupThreadInfo() {
|
||||
Map<String, Predicate<String>> filter = new HashMap<>();
|
||||
filterMap.put(ThreadInfo.class.getName(), filter);
|
||||
filter.put(V5, ThreadInfoCompositeData::isV5Attribute);
|
||||
filter.put(V6, ThreadInfoCompositeData::isV6Attribute);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the specified version of a {@linkplain CompositeType} instance.
|
||||
* @param type The current (latest) version of {@linkplain CompositeType}
|
||||
* @param version The version identifier (eg. {@linkplain TypeVersionMapper#V5})
|
||||
* @return Returns the {@linkplain CompositeType} corresponding to the requested
|
||||
* version.
|
||||
* @throws OpenDataException
|
||||
*/
|
||||
CompositeType getVersionedCompositeType(CompositeType type, String version)
|
||||
throws OpenDataException
|
||||
{
|
||||
Predicate<String> filter = getFilter(type.getTypeName(), version);
|
||||
if (filter == null) {
|
||||
return type;
|
||||
}
|
||||
|
||||
List<String> itemNames = new ArrayList<>();
|
||||
List<String> itemDesc = new ArrayList<>();
|
||||
List<OpenType<?>> itemTypes = new ArrayList<>();
|
||||
|
||||
for(String item : type.keySet()) {
|
||||
if (filter.test(item)) {
|
||||
itemNames.add(item);
|
||||
itemDesc.add(type.getDescription(item));
|
||||
itemTypes.add(getVersionedType(
|
||||
type.getType(item),
|
||||
version
|
||||
));
|
||||
}
|
||||
}
|
||||
return new CompositeType(
|
||||
type.getTypeName(),
|
||||
version != null ? version + " " + type.getDescription() : type.getDescription(),
|
||||
itemNames.toArray(new String[itemNames.size()]),
|
||||
itemDesc.toArray(new String[itemDesc.size()]),
|
||||
itemTypes.toArray(new OpenType<?>[itemTypes.size()])
|
||||
);
|
||||
}
|
||||
|
||||
private OpenType<?> getVersionedType(OpenType<?> type, String version)
|
||||
throws OpenDataException
|
||||
{
|
||||
if (type instanceof ArrayType) {
|
||||
return getVersionedArrayType((ArrayType)type, version);
|
||||
}
|
||||
if (type instanceof CompositeType) {
|
||||
return getVersionedCompositeType((CompositeType)type, version);
|
||||
}
|
||||
if (type instanceof TabularType) {
|
||||
return getVersionedTabularType((TabularType)type, version);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
private ArrayType<?> getVersionedArrayType(ArrayType<?> type, String version)
|
||||
throws OpenDataException
|
||||
{
|
||||
if (type.isPrimitiveArray()) {
|
||||
return type;
|
||||
}
|
||||
OpenType<?> ot = getVersionedType(
|
||||
type.getElementOpenType(),
|
||||
version
|
||||
);
|
||||
if (ot instanceof SimpleType) {
|
||||
return new ArrayType<>((SimpleType<?>)ot, type.isPrimitiveArray());
|
||||
} else {
|
||||
return new ArrayType<>(type.getDimension(), ot);
|
||||
}
|
||||
}
|
||||
|
||||
private TabularType getVersionedTabularType(TabularType type, String version)
|
||||
throws OpenDataException
|
||||
{
|
||||
CompositeType ct = getVersionedCompositeType(
|
||||
type.getRowType(),
|
||||
version
|
||||
);
|
||||
|
||||
if (ct != null) {
|
||||
return new TabularType(
|
||||
type.getTypeName(), type.getDescription(), ct,
|
||||
toStringArray(type.getIndexNames()));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Predicate<String> getFilter(String type, String version) {
|
||||
Map<String, Predicate<String>> versionMap = filterMap.get(type);
|
||||
if (versionMap == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return versionMap.get(version);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue