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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* 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">
|
* <tbody style="text-align:left">
|
||||||
* <tr>
|
* <tr>
|
||||||
* <th scope="row">lockedStackFrame</th>
|
* <th scope="row">lockedStackFrame</th>
|
||||||
* <td><code>CompositeData as specified in the
|
* <td><a href="ThreadInfo.html#stackTraceElement">
|
||||||
* <a href="ThreadInfo.html#StackTrace">stackTrace</a>
|
* {@code CompositeData} for {@code StackTraceElement}</a> as specified
|
||||||
* attribute defined in the {@link ThreadInfo#from
|
* in {@link ThreadInfo#from(CompositeData)} method.
|
||||||
* ThreadInfo.from} method.
|
* </td>
|
||||||
* </code></td>
|
|
||||||
* </tr>
|
* </tr>
|
||||||
* <tr>
|
* <tr>
|
||||||
* <th scope="row">lockedStackDepth</th>
|
* <th scope="row">lockedStackDepth</th>
|
||||||
|
@ -134,7 +133,7 @@ public class MonitorInfo extends LockInfo {
|
||||||
* @throws IllegalArgumentException if {@code cd} does not
|
* @throws IllegalArgumentException if {@code cd} does not
|
||||||
* represent a {@code MonitorInfo} with the attributes described
|
* represent a {@code MonitorInfo} with the attributes described
|
||||||
* above.
|
* above.
|
||||||
|
*
|
||||||
* @return a {@code MonitorInfo} object represented
|
* @return a {@code MonitorInfo} object represented
|
||||||
* by {@code cd} if {@code cd} is not {@code null};
|
* by {@code cd} if {@code cd} is not {@code null};
|
||||||
* {@code null} otherwise.
|
* {@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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
package java.lang.management;
|
package java.lang.management;
|
||||||
|
|
||||||
|
import javax.management.openmbean.ArrayType;
|
||||||
import javax.management.openmbean.CompositeData;
|
import javax.management.openmbean.CompositeData;
|
||||||
import sun.management.ManagementFactoryHelper;
|
import sun.management.ManagementFactoryHelper;
|
||||||
import sun.management.ThreadInfoCompositeData;
|
import sun.management.ThreadInfoCompositeData;
|
||||||
|
@ -110,7 +111,6 @@ public class ThreadInfo {
|
||||||
private StackTraceElement[] stackTrace;
|
private StackTraceElement[] stackTrace;
|
||||||
private MonitorInfo[] lockedMonitors;
|
private MonitorInfo[] lockedMonitors;
|
||||||
private LockInfo[] lockedSynchronizers;
|
private LockInfo[] lockedSynchronizers;
|
||||||
|
|
||||||
private static MonitorInfo[] EMPTY_MONITORS = new MonitorInfo[0];
|
private static MonitorInfo[] EMPTY_MONITORS = new MonitorInfo[0];
|
||||||
private static LockInfo[] EMPTY_SYNCS = new LockInfo[0];
|
private static LockInfo[] EMPTY_SYNCS = new LockInfo[0];
|
||||||
|
|
||||||
|
@ -264,6 +264,11 @@ public class ThreadInfo {
|
||||||
/*
|
/*
|
||||||
* Constructs a {@code ThreadInfo} object from a
|
* Constructs a {@code ThreadInfo} object from a
|
||||||
* {@link CompositeData CompositeData}.
|
* {@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) {
|
private ThreadInfo(CompositeData cd) {
|
||||||
ThreadInfoCompositeData ticd = ThreadInfoCompositeData.getInstance(cd);
|
ThreadInfoCompositeData ticd = ThreadInfoCompositeData.getInstance(cd);
|
||||||
|
@ -281,41 +286,11 @@ public class ThreadInfo {
|
||||||
suspended = ticd.suspended();
|
suspended = ticd.suspended();
|
||||||
inNative = ticd.inNative();
|
inNative = ticd.inNative();
|
||||||
stackTrace = ticd.stackTrace();
|
stackTrace = ticd.stackTrace();
|
||||||
|
lock = ticd.lockInfo();
|
||||||
// 6.0 attributes
|
lockedMonitors = ticd.lockedMonitors();
|
||||||
if (ticd.hasV6()) {
|
lockedSynchronizers = ticd.lockedSynchronizers();
|
||||||
lock = ticd.lockInfo();
|
daemon = ticd.isDaemon();
|
||||||
lockedMonitors = ticd.lockedMonitors();
|
priority = ticd.getPriority();
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -692,52 +667,105 @@ public class ThreadInfo {
|
||||||
/**
|
/**
|
||||||
* Returns a {@code ThreadInfo} object represented by the
|
* Returns a {@code ThreadInfo} object represented by the
|
||||||
* given {@code CompositeData}.
|
* 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">
|
* <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>
|
* <thead>
|
||||||
* <tr>
|
* <tr>
|
||||||
* <th scope="col">Attribute Name</th>
|
* <th scope="col">Attribute Name</th>
|
||||||
* <th scope="col">Type</th>
|
* <th scope="col">Type</th>
|
||||||
|
* <th scope="col">Since</th>
|
||||||
* </tr>
|
* </tr>
|
||||||
* </thead>
|
* </thead>
|
||||||
* <tbody style="text-align:left">
|
* <tbody style="text-align:left">
|
||||||
* <tr>
|
* <tr>
|
||||||
* <th scope="row">threadId</th>
|
* <th scope="row">threadId</th>
|
||||||
* <td>{@code java.lang.Long}</td>
|
* <td>{@code java.lang.Long}</td>
|
||||||
|
* <td>5</td>
|
||||||
* </tr>
|
* </tr>
|
||||||
* <tr>
|
* <tr>
|
||||||
* <th scope="row">threadName</th>
|
* <th scope="row">threadName</th>
|
||||||
* <td>{@code java.lang.String}</td>
|
* <td>{@code java.lang.String}</td>
|
||||||
|
* <td>5</td>
|
||||||
* </tr>
|
* </tr>
|
||||||
* <tr>
|
* <tr>
|
||||||
* <th scope="row">threadState</th>
|
* <th scope="row">threadState</th>
|
||||||
* <td>{@code java.lang.String}</td>
|
* <td>{@code java.lang.String}</td>
|
||||||
|
* <td>5</td>
|
||||||
* </tr>
|
* </tr>
|
||||||
* <tr>
|
* <tr>
|
||||||
* <th scope="row">suspended</th>
|
* <th scope="row">suspended</th>
|
||||||
* <td>{@code java.lang.Boolean}</td>
|
* <td>{@code java.lang.Boolean}</td>
|
||||||
|
* <td>5</td>
|
||||||
* </tr>
|
* </tr>
|
||||||
* <tr>
|
* <tr>
|
||||||
* <th scope="row">inNative</th>
|
* <th scope="row">inNative</th>
|
||||||
* <td>{@code java.lang.Boolean}</td>
|
* <td>{@code java.lang.Boolean}</td>
|
||||||
|
* <td>5</td>
|
||||||
* </tr>
|
* </tr>
|
||||||
* <tr>
|
* <tr>
|
||||||
* <th scope="row">blockedCount</th>
|
* <th scope="row">blockedCount</th>
|
||||||
* <td>{@code java.lang.Long}</td>
|
* <td>{@code java.lang.Long}</td>
|
||||||
|
* <td>5</td>
|
||||||
* </tr>
|
* </tr>
|
||||||
* <tr>
|
* <tr>
|
||||||
* <th scope="row">blockedTime</th>
|
* <th scope="row">blockedTime</th>
|
||||||
* <td>{@code java.lang.Long}</td>
|
* <td>{@code java.lang.Long}</td>
|
||||||
|
* <td>5</td>
|
||||||
* </tr>
|
* </tr>
|
||||||
* <tr>
|
* <tr>
|
||||||
* <th scope="row">waitedCount</th>
|
* <th scope="row">waitedCount</th>
|
||||||
* <td>{@code java.lang.Long}</td>
|
* <td>{@code java.lang.Long}</td>
|
||||||
|
* <td>5</td>
|
||||||
* </tr>
|
* </tr>
|
||||||
* <tr>
|
* <tr>
|
||||||
* <th scope="row">waitedTime</th>
|
* <th scope="row">waitedTime</th>
|
||||||
* <td>{@code java.lang.Long}</td>
|
* <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>
|
||||||
* <tr>
|
* <tr>
|
||||||
* <th scope="row">lockInfo</th>
|
* <th scope="row">lockInfo</th>
|
||||||
|
@ -745,78 +773,21 @@ public class ThreadInfo {
|
||||||
* - the mapped type for {@link LockInfo} as specified in the
|
* - the mapped type for {@link LockInfo} as specified in the
|
||||||
* {@link LockInfo#from} method.
|
* {@link LockInfo#from} method.
|
||||||
* <p>
|
* <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 {@code LockInfo} object will be constructed from
|
||||||
* the value of the {@code lockName} attribute. </td>
|
* the value of the {@code lockName} attribute.</td>
|
||||||
* </tr>
|
* <td>6</td>
|
||||||
* <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>
|
|
||||||
* </tr>
|
* </tr>
|
||||||
* <tr>
|
* <tr>
|
||||||
* <th scope="row">lockedMonitors</th>
|
* <th scope="row">lockedMonitors</th>
|
||||||
* <td>{@code javax.management.openmbean.CompositeData[]}
|
* <td>{@code javax.management.openmbean.CompositeData[]}
|
||||||
* whose element type is the mapped type for
|
* whose element type is the mapped type for
|
||||||
* {@link MonitorInfo} as specified in the
|
* {@link MonitorInfo} as specified in the
|
||||||
* {@link MonitorInfo#from Monitor.from} method.
|
* {@link MonitorInfo#from MonitorInfo.from} method.
|
||||||
* <p>
|
* <p>
|
||||||
* If {@code cd} does not contain this attribute,
|
* If the given {@code CompositeData} does not contain this attribute,
|
||||||
* this attribute will be set to an empty array. </td>
|
* this attribute will be set to an empty array.</td>
|
||||||
|
* <td>6</td>
|
||||||
* </tr>
|
* </tr>
|
||||||
* <tr>
|
* <tr>
|
||||||
* <th scope="row">lockedSynchronizers</th>
|
* <th scope="row">lockedSynchronizers</th>
|
||||||
|
@ -824,25 +795,93 @@ public class ThreadInfo {
|
||||||
* whose element type is the mapped type for
|
* whose element type is the mapped type for
|
||||||
* {@link LockInfo} as specified in the {@link LockInfo#from} method.
|
* {@link LockInfo} as specified in the {@link LockInfo#from} method.
|
||||||
* <p>
|
* <p>
|
||||||
* If {@code cd} does not contain this attribute,
|
* If the given {@code CompositeData} does not contain this attribute,
|
||||||
* this attribute will be set to an empty array. </td>
|
* this attribute will be set to an empty array.</td>
|
||||||
|
* <td>6</td>
|
||||||
* </tr>
|
* </tr>
|
||||||
* <tr>
|
* <tr>
|
||||||
* <th scope="row">daemon</th>
|
* <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>
|
||||||
* <tr>
|
* <tr>
|
||||||
* <th scope="row">priority</th>
|
* <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>{@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>
|
* </tr>
|
||||||
* </tbody>
|
* </tbody>
|
||||||
* </table>
|
* </table>
|
||||||
*
|
*
|
||||||
* @param cd {@code CompositeData} representing a {@code ThreadInfo}
|
* @param cd {@code CompositeData} representing a {@code ThreadInfo}
|
||||||
*
|
*
|
||||||
* @throws IllegalArgumentException if {@code cd} does not
|
* @throws IllegalArgumentException if the given {@code cd} and
|
||||||
* represent a {@code ThreadInfo} with the attributes described
|
* its composite type does not contain all of
|
||||||
* above.
|
* <a href="#attributes">the attributes</a> defined for a
|
||||||
|
* {@code ThreadInfo} of a specific runtime version.
|
||||||
*
|
*
|
||||||
* @return a {@code ThreadInfo} object represented
|
* @return a {@code ThreadInfo} object represented
|
||||||
* by {@code cd} if {@code cd} is not {@code null};
|
* 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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* 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() {
|
protected CompositeData getCompositeData() {
|
||||||
// CONTENTS OF THIS ARRAY MUST BE SYNCHRONIZED WITH
|
// CONTENTS OF THIS ARRAY MUST BE SYNCHRONIZED WITH
|
||||||
// lockInfoItemNames!
|
// LOCK_INFO_ATTRIBUTES!
|
||||||
final Object[] lockInfoItemValues = {
|
final Object[] lockInfoItemValues = {
|
||||||
new String(lock.getClassName()),
|
new String(lock.getClassName()),
|
||||||
lock.getIdentityHashCode(),
|
lock.getIdentityHashCode(),
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return new CompositeDataSupport(lockInfoCompositeType,
|
return new CompositeDataSupport(LOCK_INFO_COMPOSITE_TYPE,
|
||||||
lockInfoItemNames,
|
LOCK_INFO_ATTRIBUTES,
|
||||||
lockInfoItemValues);
|
lockInfoItemValues);
|
||||||
} catch (OpenDataException e) {
|
} catch (OpenDataException e) {
|
||||||
// Should never reach here
|
// 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 {
|
static {
|
||||||
try {
|
try {
|
||||||
lockInfoCompositeType = (CompositeType)
|
LOCK_INFO_COMPOSITE_TYPE = (CompositeType)
|
||||||
MappedMXBeanType.toOpenType(LockInfo.class);
|
MappedMXBeanType.toOpenType(LockInfo.class);
|
||||||
} catch (OpenDataException e) {
|
} catch (OpenDataException e) {
|
||||||
// Should never reach here
|
// Should never reach here
|
||||||
|
@ -85,13 +85,13 @@ public class LockInfoCompositeData extends LazyCompositeData {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static CompositeType getLockInfoCompositeType() {
|
static CompositeType compositeType() {
|
||||||
return lockInfoCompositeType;
|
return LOCK_INFO_COMPOSITE_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String CLASS_NAME = "className";
|
private static final String CLASS_NAME = "className";
|
||||||
private static final String IDENTITY_HASH_CODE = "identityHashCode";
|
private static final String IDENTITY_HASH_CODE = "identityHashCode";
|
||||||
private static final String[] lockInfoItemNames = {
|
private static final String[] LOCK_INFO_ATTRIBUTES = {
|
||||||
CLASS_NAME,
|
CLASS_NAME,
|
||||||
IDENTITY_HASH_CODE,
|
IDENTITY_HASH_CODE,
|
||||||
};
|
};
|
||||||
|
@ -104,7 +104,7 @@ public class LockInfoCompositeData extends LazyCompositeData {
|
||||||
throw new NullPointerException("Null CompositeData");
|
throw new NullPointerException("Null CompositeData");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isTypeMatched(lockInfoCompositeType, cd.getCompositeType())) {
|
if (!isTypeMatched(LOCK_INFO_COMPOSITE_TYPE, cd.getCompositeType())) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Unexpected composite type for LockInfo");
|
"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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* 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.CompositeData;
|
||||||
import javax.management.openmbean.CompositeDataSupport;
|
import javax.management.openmbean.CompositeDataSupport;
|
||||||
import javax.management.openmbean.OpenDataException;
|
import javax.management.openmbean.OpenDataException;
|
||||||
import java.util.Set;
|
import javax.management.openmbean.OpenType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A CompositeData for MonitorInfo for the local management support.
|
* A CompositeData for MonitorInfo for the local management support.
|
||||||
|
@ -55,14 +55,14 @@ public class MonitorInfoCompositeData extends LazyCompositeData {
|
||||||
|
|
||||||
protected CompositeData getCompositeData() {
|
protected CompositeData getCompositeData() {
|
||||||
// CONTENTS OF THIS ARRAY MUST BE SYNCHRONIZED WITH
|
// 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];
|
Object[] values = new Object[len];
|
||||||
CompositeData li = LockInfoCompositeData.toCompositeData(lock);
|
CompositeData li = LockInfoCompositeData.toCompositeData(lock);
|
||||||
|
|
||||||
for (int i = 0; i < len; i++) {
|
for (int i = 0; i < len; i++) {
|
||||||
String item = monitorInfoItemNames[i];
|
String item = MONITOR_INFO_ATTRIBUTES[i];
|
||||||
if (item.equals(LOCKED_STACK_FRAME)) {
|
if (item.equals(LOCKED_STACK_FRAME)) {
|
||||||
StackTraceElement ste = lock.getLockedStackFrame();
|
StackTraceElement ste = lock.getLockedStackFrame();
|
||||||
values[i] = (ste != null ? StackTraceElementCompositeData.
|
values[i] = (ste != null ? StackTraceElementCompositeData.
|
||||||
|
@ -76,8 +76,8 @@ public class MonitorInfoCompositeData extends LazyCompositeData {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return new CompositeDataSupport(monitorInfoCompositeType,
|
return new CompositeDataSupport(MONITOR_INFO_COMPOSITE_TYPE,
|
||||||
monitorInfoItemNames,
|
MONITOR_INFO_ATTRIBUTES,
|
||||||
values);
|
values);
|
||||||
} catch (OpenDataException e) {
|
} catch (OpenDataException e) {
|
||||||
// Should never reach here
|
// Should never reach here
|
||||||
|
@ -85,28 +85,50 @@ public class MonitorInfoCompositeData extends LazyCompositeData {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final CompositeType monitorInfoCompositeType;
|
private static final String CLASS_NAME = "className";
|
||||||
private static final String[] monitorInfoItemNames;
|
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 {
|
static {
|
||||||
try {
|
try {
|
||||||
monitorInfoCompositeType = (CompositeType)
|
MONITOR_INFO_COMPOSITE_TYPE = (CompositeType)
|
||||||
MappedMXBeanType.toOpenType(MonitorInfo.class);
|
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) {
|
} catch (OpenDataException e) {
|
||||||
// Should never reach here
|
// Should never reach here
|
||||||
throw new AssertionError(e);
|
throw new AssertionError(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static CompositeType getMonitorInfoCompositeType() {
|
static CompositeType v6CompositeType() {
|
||||||
return monitorInfoCompositeType;
|
return V6_COMPOSITE_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String CLASS_NAME = "className";
|
static CompositeType compositeType() {
|
||||||
private static final String IDENTITY_HASH_CODE = "identityHashCode";
|
return MONITOR_INFO_COMPOSITE_TYPE;
|
||||||
private static final String LOCKED_STACK_FRAME = "lockedStackFrame";
|
}
|
||||||
private static final String LOCKED_STACK_DEPTH = "lockedStackDepth";
|
|
||||||
|
|
||||||
public static String getClassName(CompositeData cd) {
|
public static String getClassName(CompositeData cd) {
|
||||||
return getString(cd, CLASS_NAME);
|
return getString(cd, CLASS_NAME);
|
||||||
|
@ -138,7 +160,8 @@ public class MonitorInfoCompositeData extends LazyCompositeData {
|
||||||
throw new NullPointerException("Null CompositeData");
|
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(
|
throw new IllegalArgumentException(
|
||||||
"Unexpected composite type for MonitorInfo");
|
"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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -25,13 +25,13 @@
|
||||||
|
|
||||||
package sun.management;
|
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.CompositeType;
|
||||||
import javax.management.openmbean.CompositeData;
|
import javax.management.openmbean.CompositeData;
|
||||||
import javax.management.openmbean.CompositeDataSupport;
|
import javax.management.openmbean.CompositeDataSupport;
|
||||||
import javax.management.openmbean.OpenDataException;
|
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.
|
* A CompositeData for StackTraceElement for the local management support.
|
||||||
|
@ -52,12 +52,7 @@ public class StackTraceElementCompositeData extends LazyCompositeData {
|
||||||
public static StackTraceElement from(CompositeData cd) {
|
public static StackTraceElement from(CompositeData cd) {
|
||||||
validateCompositeData(cd);
|
validateCompositeData(cd);
|
||||||
|
|
||||||
if (stackTraceElementV6CompositeType.equals(cd.getCompositeType())) {
|
if (STACK_TRACE_ELEMENT_COMPOSITE_TYPE.equals(cd.getCompositeType())) {
|
||||||
return new StackTraceElement(getString(cd, CLASS_NAME),
|
|
||||||
getString(cd, METHOD_NAME),
|
|
||||||
getString(cd, FILE_NAME),
|
|
||||||
getInt(cd, LINE_NUMBER));
|
|
||||||
} else {
|
|
||||||
return new StackTraceElement(getString(cd, CLASS_LOADER_NAME),
|
return new StackTraceElement(getString(cd, CLASS_LOADER_NAME),
|
||||||
getString(cd, MODULE_NAME),
|
getString(cd, MODULE_NAME),
|
||||||
getString(cd, MODULE_VERSION),
|
getString(cd, MODULE_VERSION),
|
||||||
|
@ -65,6 +60,12 @@ public class StackTraceElementCompositeData extends LazyCompositeData {
|
||||||
getString(cd, METHOD_NAME),
|
getString(cd, METHOD_NAME),
|
||||||
getString(cd, FILE_NAME),
|
getString(cd, FILE_NAME),
|
||||||
getInt(cd, LINE_NUMBER));
|
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() {
|
protected CompositeData getCompositeData() {
|
||||||
// CONTENTS OF THIS ARRAY MUST BE SYNCHRONIZED WITH
|
// CONTENTS OF THIS ARRAY MUST BE SYNCHRONIZED WITH
|
||||||
// stackTraceElementItemNames!
|
// STACK_TRACE_ELEMENT_ATTRIBUTES!
|
||||||
final Object[] stackTraceElementItemValues = {
|
final Object[] stackTraceElementItemValues = {
|
||||||
ste.getClassLoaderName(),
|
ste.getClassLoaderName(),
|
||||||
ste.getModuleName(),
|
ste.getModuleName(),
|
||||||
|
@ -87,8 +88,8 @@ public class StackTraceElementCompositeData extends LazyCompositeData {
|
||||||
ste.isNativeMethod(),
|
ste.isNativeMethod(),
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
return new CompositeDataSupport(stackTraceElementCompositeType,
|
return new CompositeDataSupport(STACK_TRACE_ELEMENT_COMPOSITE_TYPE,
|
||||||
stackTraceElementItemNames,
|
STACK_TRACE_ELEMENT_ATTRIBUTES,
|
||||||
stackTraceElementItemValues);
|
stackTraceElementItemValues);
|
||||||
} catch (OpenDataException e) {
|
} catch (OpenDataException e) {
|
||||||
// Should never reach here
|
// Should never reach here
|
||||||
|
@ -106,11 +107,7 @@ public class StackTraceElementCompositeData extends LazyCompositeData {
|
||||||
private static final String LINE_NUMBER = "lineNumber";
|
private static final String LINE_NUMBER = "lineNumber";
|
||||||
private static final String NATIVE_METHOD = "nativeMethod";
|
private static final String NATIVE_METHOD = "nativeMethod";
|
||||||
|
|
||||||
|
private static final String[] V5_ATTRIBUTES = {
|
||||||
private static final String[] stackTraceElementItemNames = {
|
|
||||||
CLASS_LOADER_NAME,
|
|
||||||
MODULE_NAME,
|
|
||||||
MODULE_VERSION,
|
|
||||||
CLASS_NAME,
|
CLASS_NAME,
|
||||||
METHOD_NAME,
|
METHOD_NAME,
|
||||||
FILE_NAME,
|
FILE_NAME,
|
||||||
|
@ -118,30 +115,48 @@ public class StackTraceElementCompositeData extends LazyCompositeData {
|
||||||
NATIVE_METHOD,
|
NATIVE_METHOD,
|
||||||
};
|
};
|
||||||
|
|
||||||
private static final String[] stackTraceElementV9ItemNames = {
|
private static final String[] V9_ATTRIBUTES = {
|
||||||
CLASS_LOADER_NAME,
|
CLASS_LOADER_NAME,
|
||||||
MODULE_NAME,
|
MODULE_NAME,
|
||||||
MODULE_VERSION,
|
MODULE_VERSION,
|
||||||
};
|
};
|
||||||
|
|
||||||
private static final CompositeType stackTraceElementCompositeType;
|
private static final String[] STACK_TRACE_ELEMENT_ATTRIBUTES =
|
||||||
private static final CompositeType stackTraceElementV6CompositeType;
|
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 {
|
static {
|
||||||
try {
|
try {
|
||||||
stackTraceElementCompositeType = (CompositeType)
|
STACK_TRACE_ELEMENT_COMPOSITE_TYPE = (CompositeType)
|
||||||
MappedMXBeanType.toOpenType(StackTraceElement.class);
|
MappedMXBeanType.toOpenType(StackTraceElement.class);
|
||||||
stackTraceElementV6CompositeType =
|
|
||||||
TypeVersionMapper.getInstance().getVersionedCompositeType(
|
OpenType<?>[] types = new OpenType<?>[V5_ATTRIBUTES.length];
|
||||||
stackTraceElementCompositeType,
|
for (int i=0; i < V5_ATTRIBUTES.length; i++) {
|
||||||
TypeVersionMapper.V6
|
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) {
|
} catch (OpenDataException e) {
|
||||||
// Should never reach here
|
// Should never reach here
|
||||||
throw new AssertionError(e);
|
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
|
* CompositeType (i.e. contain all attributes with expected
|
||||||
* names and types).
|
* names and types).
|
||||||
*/
|
*/
|
||||||
|
@ -151,22 +166,11 @@ public class StackTraceElementCompositeData extends LazyCompositeData {
|
||||||
}
|
}
|
||||||
|
|
||||||
CompositeType ct = cd.getCompositeType();
|
CompositeType ct = cd.getCompositeType();
|
||||||
if (!isTypeMatched(stackTraceElementCompositeType, ct)) {
|
if (!isTypeMatched(STACK_TRACE_ELEMENT_COMPOSITE_TYPE, ct) &&
|
||||||
if (!isTypeMatched(stackTraceElementV6CompositeType, ct)) {
|
!isTypeMatched(V5_COMPOSITE_TYPE, ct)) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Unexpected composite type for StackTraceElement");
|
"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;
|
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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* 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.ThreadInfo;
|
||||||
import java.lang.management.MonitorInfo;
|
import java.lang.management.MonitorInfo;
|
||||||
import java.lang.management.LockInfo;
|
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.CompositeType;
|
||||||
import javax.management.openmbean.CompositeData;
|
import javax.management.openmbean.CompositeData;
|
||||||
import javax.management.openmbean.CompositeDataSupport;
|
import javax.management.openmbean.CompositeDataSupport;
|
||||||
import javax.management.openmbean.OpenDataException;
|
import javax.management.openmbean.OpenDataException;
|
||||||
|
import javax.management.openmbean.OpenType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A CompositeData for ThreadInfo for the local management support.
|
* A CompositeData for ThreadInfo for the local management support.
|
||||||
|
@ -41,35 +47,21 @@ import javax.management.openmbean.OpenDataException;
|
||||||
public class ThreadInfoCompositeData extends LazyCompositeData {
|
public class ThreadInfoCompositeData extends LazyCompositeData {
|
||||||
private final ThreadInfo threadInfo;
|
private final ThreadInfo threadInfo;
|
||||||
private final CompositeData cdata;
|
private final CompositeData cdata;
|
||||||
private final boolean currentVersion;
|
|
||||||
private final boolean hasV6;
|
|
||||||
|
|
||||||
private ThreadInfoCompositeData(ThreadInfo ti) {
|
private ThreadInfoCompositeData(ThreadInfo ti) {
|
||||||
this.threadInfo = ti;
|
this.threadInfo = ti;
|
||||||
this.currentVersion = true;
|
|
||||||
this.cdata = null;
|
this.cdata = null;
|
||||||
this.hasV6 = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ThreadInfoCompositeData(CompositeData cd) {
|
private ThreadInfoCompositeData(CompositeData cd) {
|
||||||
this.threadInfo = null;
|
this.threadInfo = null;
|
||||||
this.currentVersion = ThreadInfoCompositeData.isCurrentVersion(cd);
|
|
||||||
this.cdata = cd;
|
this.cdata = cd;
|
||||||
this.hasV6 = ThreadInfoCompositeData.hasV6(cd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ThreadInfo getThreadInfo() {
|
public ThreadInfo getThreadInfo() {
|
||||||
return threadInfo;
|
return threadInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasV6() {
|
|
||||||
return hasV6;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isCurrentVersion() {
|
|
||||||
return currentVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ThreadInfoCompositeData getInstance(CompositeData cd) {
|
public static ThreadInfoCompositeData getInstance(CompositeData cd) {
|
||||||
validateCompositeData(cd);
|
validateCompositeData(cd);
|
||||||
return new ThreadInfoCompositeData(cd);
|
return new ThreadInfoCompositeData(cd);
|
||||||
|
@ -112,7 +104,7 @@ public class ThreadInfoCompositeData extends LazyCompositeData {
|
||||||
}
|
}
|
||||||
|
|
||||||
// CONTENTS OF THIS ARRAY MUST BE SYNCHRONIZED WITH
|
// CONTENTS OF THIS ARRAY MUST BE SYNCHRONIZED WITH
|
||||||
// threadInfoItemNames!
|
// THREAD_INFO_ATTRIBUTES!
|
||||||
final Object[] threadInfoItemValues = {
|
final Object[] threadInfoItemValues = {
|
||||||
threadInfo.getThreadId(),
|
threadInfo.getThreadId(),
|
||||||
threadInfo.getThreadName(),
|
threadInfo.getThreadName(),
|
||||||
|
@ -126,8 +118,8 @@ public class ThreadInfoCompositeData extends LazyCompositeData {
|
||||||
threadInfo.getLockOwnerId(),
|
threadInfo.getLockOwnerId(),
|
||||||
threadInfo.getLockOwnerName(),
|
threadInfo.getLockOwnerName(),
|
||||||
stackTraceData,
|
stackTraceData,
|
||||||
threadInfo.isSuspended(),
|
threadInfo.isSuspended(),
|
||||||
threadInfo.isInNative(),
|
threadInfo.isInNative(),
|
||||||
lockedMonitorsData,
|
lockedMonitorsData,
|
||||||
lockedSyncsData,
|
lockedSyncsData,
|
||||||
threadInfo.isDaemon(),
|
threadInfo.isDaemon(),
|
||||||
|
@ -135,8 +127,8 @@ public class ThreadInfoCompositeData extends LazyCompositeData {
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return new CompositeDataSupport(threadInfoCompositeType,
|
return new CompositeDataSupport(compositeType(),
|
||||||
threadInfoItemNames,
|
THREAD_INFO_ATTRIBTUES,
|
||||||
threadInfoItemValues);
|
threadInfoItemValues);
|
||||||
} catch (OpenDataException e) {
|
} catch (OpenDataException e) {
|
||||||
// Should never reach here
|
// 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_MONITORS = "lockedMonitors";
|
||||||
private static final String LOCKED_SYNCS = "lockedSynchronizers";
|
private static final String LOCKED_SYNCS = "lockedSynchronizers";
|
||||||
|
|
||||||
private static final String[] threadInfoItemNames = {
|
private static final String[] V5_ATTRIBUTES = {
|
||||||
THREAD_ID,
|
THREAD_ID,
|
||||||
THREAD_NAME,
|
THREAD_NAME,
|
||||||
THREAD_STATE,
|
THREAD_STATE,
|
||||||
|
@ -172,109 +164,28 @@ public class ThreadInfoCompositeData extends LazyCompositeData {
|
||||||
BLOCKED_COUNT,
|
BLOCKED_COUNT,
|
||||||
WAITED_TIME,
|
WAITED_TIME,
|
||||||
WAITED_COUNT,
|
WAITED_COUNT,
|
||||||
LOCK_INFO,
|
|
||||||
LOCK_NAME,
|
LOCK_NAME,
|
||||||
LOCK_OWNER_ID,
|
LOCK_OWNER_ID,
|
||||||
LOCK_OWNER_NAME,
|
LOCK_OWNER_NAME,
|
||||||
STACK_TRACE,
|
STACK_TRACE,
|
||||||
SUSPENDED,
|
SUSPENDED,
|
||||||
IN_NATIVE,
|
IN_NATIVE
|
||||||
LOCKED_MONITORS,
|
|
||||||
LOCKED_SYNCS,
|
|
||||||
DAEMON,
|
|
||||||
PRIORITY,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// New attributes added in 6.0 ThreadInfo
|
private static final String[] V6_ATTRIBUTES = {
|
||||||
private static final String[] threadInfoV6Attributes = {
|
|
||||||
LOCK_INFO,
|
LOCK_INFO,
|
||||||
LOCKED_MONITORS,
|
LOCKED_MONITORS,
|
||||||
LOCKED_SYNCS,
|
LOCKED_SYNCS,
|
||||||
};
|
};
|
||||||
|
|
||||||
private static final String[] threadInfoV9Attributes = {
|
private static final String[] V9_ATTRIBUTES = {
|
||||||
DAEMON,
|
DAEMON,
|
||||||
PRIORITY,
|
PRIORITY,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Current version of ThreadInfo
|
private static final String[] THREAD_INFO_ATTRIBTUES =
|
||||||
private static final CompositeType threadInfoCompositeType;
|
Stream.of(V5_ATTRIBUTES, V6_ATTRIBUTES, V9_ATTRIBUTES)
|
||||||
// Previous version of ThreadInfo
|
.flatMap(Arrays::stream).toArray(String[]::new);
|
||||||
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());
|
|
||||||
}
|
|
||||||
|
|
||||||
public long threadId() {
|
public long threadId() {
|
||||||
return getLong(cdata, THREAD_ID);
|
return getLong(cdata, THREAD_ID);
|
||||||
|
@ -333,12 +244,18 @@ public class ThreadInfoCompositeData extends LazyCompositeData {
|
||||||
return getBoolean(cdata, IN_NATIVE);
|
return getBoolean(cdata, IN_NATIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* if daemon attribute is not present, default to false.
|
||||||
|
*/
|
||||||
public boolean isDaemon() {
|
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(){
|
public int getPriority(){
|
||||||
return getInt(cdata, PRIORITY);
|
return cdata.containsKey(PRIORITY) ? getInt(cdata, PRIORITY) : Thread.NORM_PRIORITY;
|
||||||
}
|
}
|
||||||
|
|
||||||
public StackTraceElement[] stackTrace() {
|
public StackTraceElement[] stackTrace() {
|
||||||
|
@ -356,13 +273,37 @@ public class ThreadInfoCompositeData extends LazyCompositeData {
|
||||||
return stackTrace;
|
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() {
|
public LockInfo lockInfo() {
|
||||||
CompositeData lockInfoData = (CompositeData) cdata.get(LOCK_INFO);
|
if (cdata.containsKey(LOCK_INFO)) {
|
||||||
return LockInfo.from(lockInfoData);
|
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() {
|
public MonitorInfo[] lockedMonitors() {
|
||||||
|
if (!cdata.containsKey(LOCKED_MONITORS)) {
|
||||||
|
return new MonitorInfo[0];
|
||||||
|
}
|
||||||
|
|
||||||
CompositeData[] lockedMonitorsData =
|
CompositeData[] lockedMonitorsData =
|
||||||
(CompositeData[]) cdata.get(LOCKED_MONITORS);
|
(CompositeData[]) cdata.get(LOCKED_MONITORS);
|
||||||
|
|
||||||
|
@ -377,7 +318,14 @@ public class ThreadInfoCompositeData extends LazyCompositeData {
|
||||||
return monitors;
|
return monitors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an empty array if locked_monitors attribute is not present.
|
||||||
|
*/
|
||||||
public LockInfo[] lockedSynchronizers() {
|
public LockInfo[] lockedSynchronizers() {
|
||||||
|
if (!cdata.containsKey(LOCKED_SYNCS)) {
|
||||||
|
return new LockInfo[0];
|
||||||
|
}
|
||||||
|
|
||||||
CompositeData[] lockedSyncsData =
|
CompositeData[] lockedSyncsData =
|
||||||
(CompositeData[]) cdata.get(LOCKED_SYNCS);
|
(CompositeData[]) cdata.get(LOCKED_SYNCS);
|
||||||
|
|
||||||
|
@ -391,7 +339,8 @@ public class ThreadInfoCompositeData extends LazyCompositeData {
|
||||||
return locks;
|
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
|
* CompositeType (i.e. contain all attributes with expected
|
||||||
* names and types).
|
* names and types).
|
||||||
*/
|
*/
|
||||||
|
@ -401,62 +350,98 @@ public class ThreadInfoCompositeData extends LazyCompositeData {
|
||||||
}
|
}
|
||||||
|
|
||||||
CompositeType type = cd.getCompositeType();
|
CompositeType type = cd.getCompositeType();
|
||||||
boolean currentVersion = true;
|
int version;
|
||||||
if (!isTypeMatched(threadInfoCompositeType, type)) {
|
if (Arrays.stream(V9_ATTRIBUTES).anyMatch(type::containsKey)) {
|
||||||
currentVersion = false;
|
version = Runtime.version().feature();
|
||||||
// check if cd is an older version
|
} else if (Arrays.stream(V6_ATTRIBUTES).anyMatch(type::containsKey)) {
|
||||||
if (!isTypeMatched(threadInfoV5CompositeType, type) &&
|
version = 6;
|
||||||
!isTypeMatched(threadInfoV6CompositeType, type)) {
|
} else {
|
||||||
throw new IllegalArgumentException(
|
version = 5;
|
||||||
"Unexpected composite type for ThreadInfo");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CompositeData[] stackTraceData =
|
if (!isTypeMatched(ThreadInfoCompositeTypes.ofVersion(version), type)) {
|
||||||
(CompositeData[]) cd.get(STACK_TRACE);
|
|
||||||
if (stackTraceData == null) {
|
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"StackTraceElement[] is missing");
|
"Unexpected composite type for ThreadInfo of version " + version);
|
||||||
}
|
|
||||||
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.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2004, 2015, 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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -23,26 +23,26 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @test
|
* @test
|
||||||
* @bug 4982289
|
* @bug 4982289 8198253
|
||||||
* @summary Test ThreadInfo.from to return a valid
|
* @summary Test ThreadInfo.from to return a valid
|
||||||
* ThreadInfo object. Or throw exception if
|
* ThreadInfo object. Or throw exception if
|
||||||
* the input CompositeData is invalid.
|
* the input CompositeData is invalid.
|
||||||
* @author Mandy Chung
|
* @author Mandy Chung
|
||||||
*
|
*
|
||||||
* @compile OpenTypeConverter.java
|
* @build ThreadInfoCompositeData OpenTypeConverter
|
||||||
* @build ThreadInfoCompositeData
|
|
||||||
* @run main ThreadInfoCompositeData
|
* @run main ThreadInfoCompositeData
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
import javax.management.openmbean.*;
|
import javax.management.openmbean.*;
|
||||||
import java.lang.management.LockInfo;
|
import java.lang.management.LockInfo;
|
||||||
import java.lang.management.MonitorInfo;
|
import java.lang.management.MonitorInfo;
|
||||||
import java.lang.management.ThreadInfo;
|
import java.lang.management.ThreadInfo;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public class ThreadInfoCompositeData {
|
public class ThreadInfoCompositeData {
|
||||||
private static StackTraceElement[] ste = new StackTraceElement[1];
|
|
||||||
private static CompositeData[] steCD = new CompositeData[1];
|
|
||||||
private static String lockClassName = "myClass";
|
private static String lockClassName = "myClass";
|
||||||
private static int lockIdentityHashCode = 123456;
|
private static int lockIdentityHashCode = 123456;
|
||||||
private static String lockName = lockClassName + '@' +
|
private static String lockName = lockClassName + '@' +
|
||||||
|
@ -53,55 +53,100 @@ public class ThreadInfoCompositeData {
|
||||||
public static void main(String[] argv) throws Exception {
|
public static void main(String[] argv) throws Exception {
|
||||||
// A valid CompositeData is passed to ThreadInfo
|
// A valid CompositeData is passed to ThreadInfo
|
||||||
createGoodCompositeData();
|
createGoodCompositeData();
|
||||||
// A valid CompositeData for JDK 5.0 ThreadInfo
|
// A valid CompositeData for JDK 5 ThreadInfo
|
||||||
// is passed to ThreadInfo
|
// is passed to ThreadInfo
|
||||||
createV5ThreadInfo();
|
createV5ThreadInfo();
|
||||||
|
// ThreadInfo of version N can accept lockedMonitors of version >= N
|
||||||
|
withNewMonitorInfoCompositeData();
|
||||||
|
|
||||||
// An invalid CompositeData is passed to ThreadInfo.from()
|
// An invalid CompositeData is passed to ThreadInfo.from()
|
||||||
badNameCompositeData();
|
badNameCompositeData();
|
||||||
badTypeCompositeData();
|
badTypeCompositeData();
|
||||||
|
badMissingCompositeData();
|
||||||
|
withV5StackTraceCompositeData();
|
||||||
|
withInvalidMonitorInfoCompositeData();
|
||||||
System.out.println("Test passed");
|
System.out.println("Test passed");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void createGoodCompositeData() throws Exception {
|
public static void createGoodCompositeData() throws Exception {
|
||||||
CompositeType ct =
|
CompositeData cd = Factory.makeThreadInfoCompositeData();
|
||||||
new CompositeType("MyCompositeType",
|
|
||||||
"CompositeType for ThreadInfo",
|
|
||||||
validItemNames,
|
|
||||||
validItemNames,
|
|
||||||
validItemTypes);
|
|
||||||
CompositeData cd =
|
|
||||||
new CompositeDataSupport(ct,
|
|
||||||
validItemNames,
|
|
||||||
values);
|
|
||||||
ThreadInfo info = ThreadInfo.from(cd);
|
ThreadInfo info = ThreadInfo.from(cd);
|
||||||
checkThreadInfo(info);
|
checkThreadInfo(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void createV5ThreadInfo() throws Exception {
|
/*
|
||||||
String[] v5ItemNames = new String[NUM_V5_ATTS];
|
* An invalid CompositeData with JDK 9 attributes but missing JDK 6 attributes
|
||||||
OpenType[] v5ItemTypes = new OpenType[NUM_V5_ATTS];
|
*/
|
||||||
Object[] v5ItemValues = new Object[NUM_V5_ATTS];
|
public static void badMissingCompositeData() throws Exception {
|
||||||
for (int i = 0; i < NUM_V5_ATTS; i++) {
|
CompositeData cd = Factory.makeCompositeDataMissingV6();
|
||||||
v5ItemNames[i] = validItemNames[i];
|
try {
|
||||||
v5ItemTypes[i] = validItemTypes[i];
|
ThreadInfo info = ThreadInfo.from(cd);
|
||||||
v5ItemValues[i] = values[i];
|
throw new RuntimeException("IllegalArgumentException not thrown");
|
||||||
|
} catch (IllegalArgumentException e) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
static final StackTraceElement STE =
|
||||||
|
new StackTraceElement("FooClass", "getFoo", "Foo.java", 100);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Current version of ThreadInfo but an older version of StackTraceElement
|
||||||
|
*/
|
||||||
|
public static void withV5StackTraceCompositeData() throws Exception {
|
||||||
|
CompositeData cd = Factory.makeThreadInfoWithV5StackTrace();
|
||||||
|
try {
|
||||||
|
ThreadInfo info = ThreadInfo.from(cd);
|
||||||
|
throw new RuntimeException("IllegalArgumentException not thrown");
|
||||||
|
} catch (IllegalArgumentException e) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Current version of ThreadInfo but an older version of MonitorInfo
|
||||||
|
* and the value of "lockedStackFrame" attribute is null.
|
||||||
|
*/
|
||||||
|
public static void withInvalidMonitorInfoCompositeData() throws Exception {
|
||||||
|
CompositeData cd = Factory.makeThreadInfoWithIncompatibleMonitorInfo();
|
||||||
|
|
||||||
|
// verify MonitorInfo is valid
|
||||||
|
CompositeData[] monitors = (CompositeData[])cd.get("lockedMonitors");
|
||||||
|
CompositeData ste = (CompositeData)monitors[0].get("lockedStackFrame");
|
||||||
|
if (((Integer)monitors[0].get("lockedStackDepth")) >= 0 || ste != null) {
|
||||||
|
throw new RuntimeException("Expected negative stack depth and null stack frame");
|
||||||
}
|
}
|
||||||
CompositeType ct =
|
MonitorInfo minfo = MonitorInfo.from(monitors[0]);
|
||||||
new CompositeType("MyCompositeType",
|
checkLockInfo(minfo);
|
||||||
"CompositeType for JDK 5.0 ThreadInfo",
|
if (minfo.getLockedStackFrame() != null) {
|
||||||
v5ItemNames,
|
throw new RuntimeException("Expected null stack frame");
|
||||||
v5ItemNames,
|
}
|
||||||
v5ItemTypes);
|
|
||||||
CompositeData cd =
|
try {
|
||||||
new CompositeDataSupport(ct,
|
ThreadInfo info = ThreadInfo.from(cd);
|
||||||
v5ItemNames,
|
throw new RuntimeException("IllegalArgumentException not thrown");
|
||||||
v5ItemValues);
|
} catch (IllegalArgumentException e) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ThreadInfo of version N can accept lockedMonitors of version >= N
|
||||||
|
*/
|
||||||
|
public static void withNewMonitorInfoCompositeData() throws Exception {
|
||||||
|
CompositeData cd = Factory.makeThreadInfoWithNewMonitorInfo();
|
||||||
ThreadInfo info = ThreadInfo.from(cd);
|
ThreadInfo info = ThreadInfo.from(cd);
|
||||||
checkThreadInfo(info);
|
checkThreadInfo(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test CompositeData representing JDK 5 ThreadInfo
|
||||||
|
*/
|
||||||
|
public static void createV5ThreadInfo() throws Exception {
|
||||||
|
CompositeData cd = Factory.makeThreadInfoV5CompositeData();
|
||||||
|
ThreadInfo info = ThreadInfo.from(cd);
|
||||||
|
checkThreadInfoV5(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void checkThreadInfo(ThreadInfo info) throws Exception {
|
static void checkThreadInfoV5(ThreadInfo info) {
|
||||||
if (info.getThreadId() != ((Long) values[THREAD_ID]).longValue()) {
|
Object[] values = Factory.VALUES;
|
||||||
|
|
||||||
|
if (info.getThreadId() != ((Long) values[THREAD_ID]).longValue()) {
|
||||||
throw new RuntimeException("Thread Id = " + info.getThreadId() +
|
throw new RuntimeException("Thread Id = " + info.getThreadId() +
|
||||||
" expected = " + values[THREAD_ID]);
|
" expected = " + values[THREAD_ID]);
|
||||||
}
|
}
|
||||||
|
@ -148,30 +193,35 @@ public class ThreadInfoCompositeData {
|
||||||
info.getLockOwnerName() + " expected = " +
|
info.getLockOwnerName() + " expected = " +
|
||||||
values[LOCK_OWNER_NAME]);
|
values[LOCK_OWNER_NAME]);
|
||||||
}
|
}
|
||||||
if (!values[DAEMON].equals(info.isDaemon())) {
|
|
||||||
throw new RuntimeException("Daemon = " +
|
|
||||||
info.isDaemon() + " expected = " +
|
|
||||||
values[DAEMON]);
|
|
||||||
}
|
|
||||||
|
|
||||||
checkStackTrace(info.getStackTrace());
|
checkStackTrace(info.getStackTrace());
|
||||||
|
|
||||||
checkLockInfo(info.getLockInfo());
|
checkLockInfo(info.getLockInfo());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void checkThreadInfo(ThreadInfo info) {
|
||||||
|
Object[] values = Factory.VALUES;
|
||||||
|
|
||||||
|
checkThreadInfoV5(info);
|
||||||
|
|
||||||
|
if (!values[DAEMON].equals(info.isDaemon())) {
|
||||||
|
throw new RuntimeException("Daemon = " +
|
||||||
|
info.isDaemon() + " expected = " + values[DAEMON]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void checkStackTrace(StackTraceElement[] s)
|
private static void checkStackTrace(StackTraceElement[] s) {
|
||||||
throws Exception {
|
if (s.length != 1) {
|
||||||
if (ste.length != s.length) {
|
|
||||||
throw new RuntimeException("Stack Trace length = " +
|
throw new RuntimeException("Stack Trace length = " +
|
||||||
s.length + " expected = " + ste.length);
|
s.length + " expected = 1");
|
||||||
}
|
}
|
||||||
|
|
||||||
StackTraceElement s1 = ste[0];
|
StackTraceElement s1 = STE;
|
||||||
StackTraceElement s2 = s[0];
|
StackTraceElement s2 = s[0];
|
||||||
|
|
||||||
if (!s1.getClassName().equals(s2.getClassName())) {
|
// these attributes may be null
|
||||||
throw new RuntimeException("Class name = " +
|
if (!Objects.equals(s1.getClassLoaderName(), s2.getClassLoaderName())) {
|
||||||
s2.getClassName() + " expected = " + s1.getClassName());
|
throw new RuntimeException("Class loader name = " +
|
||||||
|
s2.getClassLoaderName() + " expected = " + s1.getClassLoaderName());
|
||||||
}
|
}
|
||||||
if (!Objects.equals(s1.getModuleName(), s2.getModuleName())) {
|
if (!Objects.equals(s1.getModuleName(), s2.getModuleName())) {
|
||||||
throw new RuntimeException("Module name = " +
|
throw new RuntimeException("Module name = " +
|
||||||
|
@ -181,6 +231,11 @@ public class ThreadInfoCompositeData {
|
||||||
throw new RuntimeException("Module version = " +
|
throw new RuntimeException("Module version = " +
|
||||||
s2.getModuleVersion() + " expected = " + s1.getModuleVersion());
|
s2.getModuleVersion() + " expected = " + s1.getModuleVersion());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!s1.getClassName().equals(s2.getClassName())) {
|
||||||
|
throw new RuntimeException("Class name = " +
|
||||||
|
s2.getClassName() + " expected = " + s1.getClassName());
|
||||||
|
}
|
||||||
if (!s1.getMethodName().equals(s2.getMethodName())) {
|
if (!s1.getMethodName().equals(s2.getMethodName())) {
|
||||||
throw new RuntimeException("Method name = " +
|
throw new RuntimeException("Method name = " +
|
||||||
s2.getMethodName() + " expected = " + s1.getMethodName());
|
s2.getMethodName() + " expected = " + s1.getMethodName());
|
||||||
|
@ -195,8 +250,7 @@ public class ThreadInfoCompositeData {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void checkLockInfo(LockInfo li)
|
private static void checkLockInfo(LockInfo li) {
|
||||||
throws Exception {
|
|
||||||
if (!li.getClassName().equals(lockInfo.getClassName())) {
|
if (!li.getClassName().equals(lockInfo.getClassName())) {
|
||||||
throw new RuntimeException("Class Name = " +
|
throw new RuntimeException("Class Name = " +
|
||||||
li.getClassName() + " expected = " + lockInfo.getClassName());
|
li.getClassName() + " expected = " + lockInfo.getClassName());
|
||||||
|
@ -209,227 +263,493 @@ public class ThreadInfoCompositeData {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void badNameCompositeData() throws Exception {
|
public static void badNameCompositeData() throws Exception {
|
||||||
CompositeType ct =
|
CompositeData cd = Factory.makeCompositeDataWithBadNames();
|
||||||
new CompositeType("MyCompositeType",
|
|
||||||
"CompositeType for ThreadInfo",
|
|
||||||
badItemNames,
|
|
||||||
badItemNames,
|
|
||||||
validItemTypes);
|
|
||||||
CompositeData cd =
|
|
||||||
new CompositeDataSupport(ct,
|
|
||||||
badItemNames,
|
|
||||||
values);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ThreadInfo info = ThreadInfo.from(cd);
|
ThreadInfo info = ThreadInfo.from(cd);
|
||||||
} catch (IllegalArgumentException e) {
|
throw new RuntimeException("IllegalArgumentException not thrown");
|
||||||
System.out.println("Expected exception: " +
|
} catch (IllegalArgumentException e) { }
|
||||||
e.getMessage());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
throw new RuntimeException(
|
|
||||||
"IllegalArgumentException not thrown");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void badTypeCompositeData() throws Exception {
|
public static void badTypeCompositeData() throws Exception {
|
||||||
CompositeType ct =
|
CompositeData cd = Factory.makeCompositeDataWithBadTypes();
|
||||||
new CompositeType("MyCompositeType",
|
|
||||||
"CompositeType for ThreadInfo",
|
|
||||||
validItemNames,
|
|
||||||
validItemNames,
|
|
||||||
badItemTypes);
|
|
||||||
|
|
||||||
// patch values[STACK_TRACE] to Long
|
|
||||||
values[STACK_TRACE] = new Long(1000);
|
|
||||||
values[LOCK_INFO] = new Long(1000);
|
|
||||||
CompositeData cd =
|
|
||||||
new CompositeDataSupport(ct,
|
|
||||||
validItemNames,
|
|
||||||
values);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ThreadInfo info = ThreadInfo.from(cd);
|
ThreadInfo info = ThreadInfo.from(cd);
|
||||||
} catch (IllegalArgumentException e) {
|
throw new RuntimeException("IllegalArgumentException not thrown");
|
||||||
System.out.println("Expected exception: " +
|
} catch (IllegalArgumentException e) { }
|
||||||
e.getMessage());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
throw new RuntimeException(
|
|
||||||
"IllegalArgumentException not thrown");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final int THREAD_ID = 0;
|
private static final int THREAD_ID = 0;
|
||||||
private static final int THREAD_NAME = 1;
|
private static final int THREAD_NAME = 1;
|
||||||
private static final int THREAD_STATE = 2;
|
private static final int THREAD_STATE = 2;
|
||||||
private static final int BLOCKED_TIME = 3;
|
private static final int BLOCKED_TIME = 3;
|
||||||
private static final int BLOCKED_COUNT = 4;
|
private static final int BLOCKED_COUNT = 4;
|
||||||
private static final int WAITED_TIME = 5;
|
private static final int WAITED_TIME = 5;
|
||||||
private static final int WAITED_COUNT = 6;
|
private static final int WAITED_COUNT = 6;
|
||||||
private static final int LOCK_NAME = 7;
|
private static final int LOCK_NAME = 7;
|
||||||
private static final int LOCK_OWNER_ID = 8;
|
private static final int LOCK_OWNER_ID = 8;
|
||||||
private static final int LOCK_OWNER_NAME = 9;
|
private static final int LOCK_OWNER_NAME = 9;
|
||||||
private static final int STACK_TRACE = 10;
|
private static final int STACK_TRACE = 10;
|
||||||
private static final int SUSPENDED = 11;
|
private static final int SUSPENDED = 11;
|
||||||
private static final int IN_NATIVE = 12;
|
private static final int IN_NATIVE = 12;
|
||||||
private static final int NUM_V5_ATTS = 13;
|
// JDK 6 ThreadInfo attributes
|
||||||
// JDK 6.0 ThreadInfo attributes
|
private static final int LOCK_INFO = 13;
|
||||||
private static final int LOCK_INFO = 13;
|
private static final int LOCKED_MONITORS = 14;
|
||||||
// JDK 9.0 ThreadInfo attributes
|
private static final int LOCKED_SYNCS = 15;
|
||||||
private static final int DAEMON = 14;
|
// JDK 9 ThreadInfo attributes
|
||||||
private static final int PRIORITY = 15;
|
private static final int DAEMON = 16;
|
||||||
|
private static final int PRIORITY = 17;
|
||||||
|
|
||||||
private static final String[] validItemNames = {
|
static class Factory {
|
||||||
"threadId",
|
|
||||||
"threadName",
|
|
||||||
"threadState",
|
|
||||||
"blockedTime",
|
|
||||||
"blockedCount",
|
|
||||||
"waitedTime",
|
|
||||||
"waitedCount",
|
|
||||||
"lockName",
|
|
||||||
"lockOwnerId",
|
|
||||||
"lockOwnerName",
|
|
||||||
"stackTrace",
|
|
||||||
"suspended",
|
|
||||||
"inNative",
|
|
||||||
"lockInfo",
|
|
||||||
"daemon",
|
|
||||||
"priority",
|
|
||||||
};
|
|
||||||
|
|
||||||
private static OpenType[] validItemTypes = {
|
static final CompositeType STE_COMPOSITE_TYPE;
|
||||||
SimpleType.LONG,
|
static final CompositeType LOCK_INFO_COMPOSITE_TYPE;
|
||||||
SimpleType.STRING,
|
static final CompositeType MONITOR_INFO_COMPOSITE_TYPE;
|
||||||
SimpleType.STRING,
|
static final ArrayType STE_ARRAY_COMPOSITE_TYPE;
|
||||||
SimpleType.LONG,
|
static final ArrayType LOCK_INFO_ARRAY_COMPOSITE_TYPE;
|
||||||
SimpleType.LONG,
|
static final ArrayType MONITOR_INFO_ARRAY_COMPOSITE_TYPE;
|
||||||
SimpleType.LONG,
|
|
||||||
SimpleType.LONG,
|
|
||||||
SimpleType.STRING,
|
|
||||||
SimpleType.LONG,
|
|
||||||
SimpleType.STRING,
|
|
||||||
null, // ArrayType for StackTraceElement[]
|
|
||||||
SimpleType.BOOLEAN,
|
|
||||||
SimpleType.BOOLEAN,
|
|
||||||
null, // CompositeType for LockInfo
|
|
||||||
SimpleType.BOOLEAN,
|
|
||||||
SimpleType.INTEGER,
|
|
||||||
};
|
|
||||||
|
|
||||||
private static Object[] values = {
|
static {
|
||||||
new Long(100),
|
CompositeType steCType = null;
|
||||||
"FooThread",
|
CompositeType lockInfoCType = null;
|
||||||
"RUNNABLE",
|
CompositeType monitorInfoCType = null;
|
||||||
new Long(200),
|
ArrayType steArrayType = null;
|
||||||
new Long(10),
|
ArrayType lockInfoArrayType = null;
|
||||||
new Long(300),
|
ArrayType monitorInfoArrayType = null;
|
||||||
new Long(20),
|
|
||||||
lockName,
|
|
||||||
new Long(99),
|
|
||||||
"BarThread",
|
|
||||||
steCD,
|
|
||||||
new Boolean(false),
|
|
||||||
new Boolean(false),
|
|
||||||
null, // To be initialized to lockInfoCD
|
|
||||||
new Boolean(false),
|
|
||||||
Thread.NORM_PRIORITY,
|
|
||||||
};
|
|
||||||
|
|
||||||
private static final String[] steItemNames = {
|
try {
|
||||||
"classLoaderName",
|
steCType = (CompositeType) OpenTypeConverter.toOpenType(StackTraceElement.class);
|
||||||
"moduleName",
|
lockInfoCType = (CompositeType) OpenTypeConverter.toOpenType(LockInfo.class);
|
||||||
"moduleVersion",
|
monitorInfoCType = (CompositeType) OpenTypeConverter.toOpenType(MonitorInfo.class);
|
||||||
"className",
|
steArrayType = new ArrayType(1, steCType);
|
||||||
"methodName",
|
lockInfoArrayType = new ArrayType(1, lockInfoCType);
|
||||||
"fileName",
|
monitorInfoArrayType = new ArrayType(1, monitorInfoCType);
|
||||||
"lineNumber",
|
} catch (Exception e) {
|
||||||
"nativeMethod",
|
throw new RuntimeException(e);
|
||||||
};
|
}
|
||||||
|
STE_COMPOSITE_TYPE = steCType;
|
||||||
|
LOCK_INFO_COMPOSITE_TYPE = lockInfoCType;
|
||||||
|
MONITOR_INFO_COMPOSITE_TYPE = monitorInfoCType;
|
||||||
|
STE_ARRAY_COMPOSITE_TYPE = steArrayType;
|
||||||
|
LOCK_INFO_ARRAY_COMPOSITE_TYPE = lockInfoArrayType;
|
||||||
|
MONITOR_INFO_ARRAY_COMPOSITE_TYPE = monitorInfoArrayType;
|
||||||
|
}
|
||||||
|
|
||||||
private static final String[] lockInfoItemNames = {
|
static CompositeData makeThreadInfoCompositeData() throws OpenDataException {
|
||||||
"className",
|
CompositeType ct = new CompositeType("MyCompositeType",
|
||||||
"identityHashCode",
|
"CompositeType for ThreadInfo",
|
||||||
};
|
ITEM_NAMES,
|
||||||
|
ITEM_NAMES,
|
||||||
|
ITEM_TYPES);
|
||||||
|
return new CompositeDataSupport(ct, ITEM_NAMES, VALUES);
|
||||||
|
}
|
||||||
|
|
||||||
static {
|
static CompositeData makeThreadInfoV5CompositeData() throws OpenDataException {
|
||||||
// create stack trace element
|
CompositeType ct = new CompositeType("MyCompositeType",
|
||||||
ste[0] = new StackTraceElement("FooClass", "getFoo", "Foo.java", 100);
|
"CompositeType for JDK 5 ThreadInfo",
|
||||||
|
V5_ITEM_NAMES,
|
||||||
|
V5_ITEM_NAMES,
|
||||||
|
V5_ITEM_TYPES);
|
||||||
|
return new CompositeDataSupport(ct, V5_ITEM_NAMES, V5_VALUES);
|
||||||
|
}
|
||||||
|
|
||||||
// initialize the ste[0] and values and validItemTypes
|
static CompositeData makeCompositeDataWithBadTypes() throws OpenDataException {
|
||||||
try {
|
OpenType[] badItemTypes = {
|
||||||
CompositeType steCType = (CompositeType)
|
SimpleType.LONG,
|
||||||
OpenTypeConverter.toOpenType(StackTraceElement.class);
|
SimpleType.STRING,
|
||||||
validItemTypes[STACK_TRACE] = new ArrayType(1, steCType);
|
SimpleType.STRING,
|
||||||
|
SimpleType.LONG,
|
||||||
final Object[] steValue = {
|
SimpleType.LONG,
|
||||||
ste[0].getClassLoaderName(),
|
SimpleType.LONG,
|
||||||
ste[0].getModuleName(),
|
SimpleType.LONG,
|
||||||
ste[0].getModuleVersion(),
|
SimpleType.STRING,
|
||||||
ste[0].getClassName(),
|
SimpleType.LONG,
|
||||||
ste[0].getMethodName(),
|
SimpleType.STRING,
|
||||||
ste[0].getFileName(),
|
SimpleType.LONG, // bad type
|
||||||
new Integer(ste[0].getLineNumber()),
|
SimpleType.BOOLEAN,
|
||||||
new Boolean(ste[0].isNativeMethod()),
|
SimpleType.BOOLEAN,
|
||||||
|
SimpleType.LONG, // bad type
|
||||||
|
SimpleType.LONG, // bad type
|
||||||
|
SimpleType.LONG, // bad type
|
||||||
|
SimpleType.BOOLEAN,
|
||||||
|
SimpleType.INTEGER,
|
||||||
};
|
};
|
||||||
|
|
||||||
steCD[0] =
|
CompositeType ct =
|
||||||
new CompositeDataSupport(steCType,
|
new CompositeType("Bad item types",
|
||||||
steItemNames,
|
"CompositeType for ThreadInfo",
|
||||||
steValue);
|
ITEM_NAMES,
|
||||||
|
ITEM_NAMES,
|
||||||
|
badItemTypes);
|
||||||
|
|
||||||
CompositeType lockInfoCType = (CompositeType)
|
// Copy before mutating to avoid affecting other tests.
|
||||||
OpenTypeConverter.toOpenType(LockInfo.class);
|
Object[] localValues = VALUES.clone();
|
||||||
validItemTypes[LOCK_INFO] = lockInfoCType;
|
|
||||||
|
|
||||||
final Object[] lockInfoValue = {
|
// patch values[STACK_TRACE] to Long
|
||||||
|
localValues[STACK_TRACE] = Long.valueOf(1000);
|
||||||
|
localValues[LOCK_INFO] = Long.valueOf(1000);
|
||||||
|
localValues[LOCKED_MONITORS] = Long.valueOf(1000);
|
||||||
|
localValues[LOCKED_SYNCS] = Long.valueOf(1000);
|
||||||
|
return new CompositeDataSupport(ct, ITEM_NAMES, localValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
static CompositeData makeCompositeDataWithBadNames() throws OpenDataException {
|
||||||
|
String[] badItemNames = ITEM_NAMES.clone();
|
||||||
|
badItemNames[STACK_TRACE] = "BadStackTrace"; // bad item name
|
||||||
|
|
||||||
|
CompositeType ct = new CompositeType("Bad item names",
|
||||||
|
"CompositeType for ThreadInfo",
|
||||||
|
badItemNames,
|
||||||
|
badItemNames,
|
||||||
|
ITEM_TYPES);
|
||||||
|
return new CompositeDataSupport(ct,
|
||||||
|
badItemNames,
|
||||||
|
VALUES);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create a CompositeData of ThreadInfo without JDK 6 attributes
|
||||||
|
*/
|
||||||
|
static CompositeData makeCompositeDataMissingV6() throws OpenDataException {
|
||||||
|
String[] itemNames = concat(V5_ITEM_NAMES, V9_ITEM_NAMES).toArray(String[]::new);
|
||||||
|
OpenType[] itemTypes = concat(V5_ITEM_TYPES, V9_ITEM_TYPES).toArray(OpenType[]::new);
|
||||||
|
Object[] values = concat(V5_VALUES, V9_VALUES).toArray(Object[]::new);
|
||||||
|
|
||||||
|
CompositeType ct =
|
||||||
|
new CompositeType("InvalidCompositeType",
|
||||||
|
"CompositeType for ThreadInfo",
|
||||||
|
itemNames,
|
||||||
|
itemNames,
|
||||||
|
itemTypes);
|
||||||
|
return new CompositeDataSupport(ct, itemNames, values);
|
||||||
|
}
|
||||||
|
|
||||||
|
static CompositeData makeStackTraceElement() {
|
||||||
|
Object[] steValue = {
|
||||||
|
STE.getClassLoaderName(),
|
||||||
|
STE.getModuleName(),
|
||||||
|
STE.getModuleVersion(),
|
||||||
|
STE.getClassName(),
|
||||||
|
STE.getMethodName(),
|
||||||
|
STE.getFileName(),
|
||||||
|
Integer.valueOf(STE.getLineNumber()),
|
||||||
|
Boolean.valueOf(STE.isNativeMethod()),
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
return new CompositeDataSupport(STE_COMPOSITE_TYPE,
|
||||||
|
STE_ITEM_NAMES,
|
||||||
|
steValue);
|
||||||
|
} catch (OpenDataException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static CompositeData makeStackTraceElementV5() throws OpenDataException {
|
||||||
|
CompositeType steV5CType =
|
||||||
|
new CompositeType("JDK 5 StackTraceElement",
|
||||||
|
"CompositeType for JDK 5 StackTraceElement",
|
||||||
|
STE_V5_ITEM_NAMES,
|
||||||
|
STE_V5_ITEM_NAMES,
|
||||||
|
STE_V5_ITEM_TYPES);
|
||||||
|
|
||||||
|
Object[] steV5Value = {
|
||||||
|
STE.getClassName(),
|
||||||
|
STE.getMethodName(),
|
||||||
|
STE.getFileName(),
|
||||||
|
Integer.valueOf(STE.getLineNumber()),
|
||||||
|
Boolean.valueOf(STE.isNativeMethod()),
|
||||||
|
};
|
||||||
|
|
||||||
|
return new CompositeDataSupport(steV5CType, STE_V5_ITEM_NAMES, steV5Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create a CompositeData of ThreadInfo without JDK 5 StackTraceElement
|
||||||
|
*/
|
||||||
|
static CompositeData makeThreadInfoWithV5StackTrace() throws OpenDataException {
|
||||||
|
OpenType[] badTypes = ITEM_TYPES.clone();
|
||||||
|
Object[] badValues = VALUES.clone();
|
||||||
|
|
||||||
|
CompositeData[] stackTrace = new CompositeData[1];
|
||||||
|
stackTrace[0] = makeStackTraceElementV5();
|
||||||
|
badTypes[STACK_TRACE] = new ArrayType(1, stackTrace[0].getCompositeType());
|
||||||
|
badValues[STACK_TRACE] = stackTrace;
|
||||||
|
CompositeType ct = new CompositeType("CompositeType",
|
||||||
|
"ThreadInfo with JDK 5 StackTraceElement",
|
||||||
|
ITEM_NAMES,
|
||||||
|
ITEM_NAMES,
|
||||||
|
badTypes);
|
||||||
|
return new CompositeDataSupport(ct, ITEM_NAMES, badValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create MonitorInfo with JDK 5 StackTraceElement (i.e. JDK 6 MonitorInfo)
|
||||||
|
* The value of "lockedStackFrame" attribute is null to ensure that
|
||||||
|
* the validation is done.
|
||||||
|
*/
|
||||||
|
static CompositeData makeV6MonitorInfo() throws OpenDataException {
|
||||||
|
CompositeData steV5 = makeStackTraceElementV5();
|
||||||
|
|
||||||
|
String[] names = MONITOR_INFO_COMPOSITE_TYPE.keySet().toArray(new String[0]);
|
||||||
|
OpenType[] types = new OpenType[names.length];
|
||||||
|
for (int i=0; i < names.length; i++) {
|
||||||
|
String n = names[i];
|
||||||
|
types[i] = "lockedStackFrame".equals(n)
|
||||||
|
? steV5.getCompositeType()
|
||||||
|
: MONITOR_INFO_COMPOSITE_TYPE.getType(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
CompositeType ctype =
|
||||||
|
new CompositeType("JDK 6 MonitorInfo",
|
||||||
|
"CompositeType for JDK 6 MonitorInfo",
|
||||||
|
names,
|
||||||
|
names,
|
||||||
|
types);
|
||||||
|
|
||||||
|
Object[] values = {
|
||||||
|
lockClassName,
|
||||||
|
lockIdentityHashCode,
|
||||||
|
-1,
|
||||||
|
null
|
||||||
|
};
|
||||||
|
|
||||||
|
return new CompositeDataSupport(ctype, names, values);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create a CompositeData of ThreadInfo with incompatible MonitorInfo
|
||||||
|
*/
|
||||||
|
static CompositeData makeThreadInfoWithIncompatibleMonitorInfo() throws OpenDataException {
|
||||||
|
OpenType[] badTypes = ITEM_TYPES.clone();
|
||||||
|
Object[] badValues = VALUES.clone();
|
||||||
|
|
||||||
|
CompositeData[] lockedMonitors = new CompositeData[1];
|
||||||
|
lockedMonitors[0] = makeV6MonitorInfo();
|
||||||
|
badTypes[LOCKED_MONITORS] = new ArrayType(1, lockedMonitors[0].getCompositeType());
|
||||||
|
badValues[LOCKED_MONITORS] = lockedMonitors;
|
||||||
|
CompositeType ct = new CompositeType("CompositeType",
|
||||||
|
"ThreadInfo with incompatible MonitorInfo",
|
||||||
|
ITEM_NAMES,
|
||||||
|
ITEM_NAMES,
|
||||||
|
badTypes);
|
||||||
|
return new CompositeDataSupport(ct, ITEM_NAMES, badValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
static CompositeData makeNewMonitorInfo() throws OpenDataException {
|
||||||
|
String[] names = Stream.concat(MONITOR_INFO_COMPOSITE_TYPE.keySet().stream(),
|
||||||
|
Stream.of("extra")).toArray(String[]::new);
|
||||||
|
OpenType[] types = new OpenType[names.length];
|
||||||
|
for (int i=0; i < names.length; i++) {
|
||||||
|
String n = names[i];
|
||||||
|
types[i] = "extra".equals(n)
|
||||||
|
? SimpleType.STRING
|
||||||
|
: MONITOR_INFO_COMPOSITE_TYPE.getType(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
CompositeType compositeType =
|
||||||
|
new CompositeType("JDK X MonitorInfo",
|
||||||
|
"CompositeType for JDK X MonitorInfo",
|
||||||
|
names,
|
||||||
|
names,
|
||||||
|
types);
|
||||||
|
|
||||||
|
Object[] values = {
|
||||||
|
lockClassName,
|
||||||
|
lockIdentityHashCode,
|
||||||
|
Integer.valueOf(1),
|
||||||
|
makeStackTraceElement(),
|
||||||
|
"extra"
|
||||||
|
};
|
||||||
|
|
||||||
|
return new CompositeDataSupport(compositeType, names, values);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create a CompositeData of ThreadInfo with a newer version of MonitorInfo
|
||||||
|
*/
|
||||||
|
static CompositeData makeThreadInfoWithNewMonitorInfo() throws OpenDataException {
|
||||||
|
OpenType[] types = ITEM_TYPES.clone();
|
||||||
|
Object[] badValues = VALUES.clone();
|
||||||
|
|
||||||
|
CompositeData[] lockedMonitors = new CompositeData[1];
|
||||||
|
lockedMonitors[0] = makeNewMonitorInfo();
|
||||||
|
types[LOCKED_MONITORS] = new ArrayType(1, lockedMonitors[0].getCompositeType());
|
||||||
|
badValues[LOCKED_MONITORS] = lockedMonitors;
|
||||||
|
CompositeType ct = new CompositeType("CompositeType",
|
||||||
|
"ThreadInfo with JDK 5 MonitorInfo",
|
||||||
|
ITEM_NAMES,
|
||||||
|
ITEM_NAMES,
|
||||||
|
types);
|
||||||
|
return new CompositeDataSupport(ct, ITEM_NAMES, badValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
static CompositeData makeLockInfo() {
|
||||||
|
Object[] lockInfoValue = {
|
||||||
lockInfo.getClassName(),
|
lockInfo.getClassName(),
|
||||||
lockInfo.getIdentityHashCode(),
|
lockInfo.getIdentityHashCode(),
|
||||||
};
|
};
|
||||||
|
|
||||||
values[LOCK_INFO] =
|
try {
|
||||||
new CompositeDataSupport(lockInfoCType,
|
return new CompositeDataSupport(LOCK_INFO_COMPOSITE_TYPE,
|
||||||
lockInfoItemNames,
|
LOCK_INFO_ITEM_NAMES,
|
||||||
lockInfoValue);
|
lockInfoValue);
|
||||||
} catch (Exception e) {
|
} catch (OpenDataException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static CompositeData[] makeLockedSynchronizers() {
|
||||||
|
CompositeData[] lockedSyncs = new CompositeData[1];
|
||||||
|
lockedSyncs[0] = makeLockInfo();
|
||||||
|
return lockedSyncs;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CompositeData[] makeLockedMonitors() {
|
||||||
|
CompositeData[] lockedMonitorsCD = new CompositeData[1];
|
||||||
|
|
||||||
|
Object[] lockedMonitorsValue = {
|
||||||
|
lockInfo.getClassName(),
|
||||||
|
lockInfo.getIdentityHashCode(),
|
||||||
|
makeStackTraceElement(),
|
||||||
|
Integer.valueOf(1),
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
lockedMonitorsCD[0] =
|
||||||
|
new CompositeDataSupport(MONITOR_INFO_COMPOSITE_TYPE,
|
||||||
|
LOCKED_MONITORS_ITEM_NAMES,
|
||||||
|
lockedMonitorsValue);
|
||||||
|
} catch (OpenDataException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
return lockedMonitorsCD;
|
||||||
|
}
|
||||||
|
|
||||||
|
static final String[] V5_ITEM_NAMES = {
|
||||||
|
"threadId",
|
||||||
|
"threadName",
|
||||||
|
"threadState",
|
||||||
|
"blockedTime",
|
||||||
|
"blockedCount",
|
||||||
|
"waitedTime",
|
||||||
|
"waitedCount",
|
||||||
|
"lockName",
|
||||||
|
"lockOwnerId",
|
||||||
|
"lockOwnerName",
|
||||||
|
"stackTrace",
|
||||||
|
"suspended",
|
||||||
|
"inNative",
|
||||||
|
};
|
||||||
|
|
||||||
|
static final String[] V6_ITEM_NAMES = {
|
||||||
|
"lockInfo",
|
||||||
|
"lockedMonitors",
|
||||||
|
"lockedSynchronizers",
|
||||||
|
};
|
||||||
|
|
||||||
|
static final String[] V9_ITEM_NAMES = {
|
||||||
|
"daemon",
|
||||||
|
"priority",
|
||||||
|
};
|
||||||
|
|
||||||
|
static final OpenType[] V5_ITEM_TYPES = {
|
||||||
|
SimpleType.LONG,
|
||||||
|
SimpleType.STRING,
|
||||||
|
SimpleType.STRING,
|
||||||
|
SimpleType.LONG,
|
||||||
|
SimpleType.LONG,
|
||||||
|
SimpleType.LONG,
|
||||||
|
SimpleType.LONG,
|
||||||
|
SimpleType.STRING,
|
||||||
|
SimpleType.LONG,
|
||||||
|
SimpleType.STRING,
|
||||||
|
STE_ARRAY_COMPOSITE_TYPE,
|
||||||
|
SimpleType.BOOLEAN,
|
||||||
|
SimpleType.BOOLEAN,
|
||||||
|
};
|
||||||
|
|
||||||
|
static final OpenType[] V6_ITEM_TYPES = {
|
||||||
|
LOCK_INFO_COMPOSITE_TYPE,
|
||||||
|
MONITOR_INFO_ARRAY_COMPOSITE_TYPE,
|
||||||
|
LOCK_INFO_ARRAY_COMPOSITE_TYPE,
|
||||||
|
};
|
||||||
|
|
||||||
|
static final OpenType[] V9_ITEM_TYPES = {
|
||||||
|
SimpleType.BOOLEAN,
|
||||||
|
SimpleType.INTEGER,
|
||||||
|
};
|
||||||
|
|
||||||
|
static final String[] STE_ITEM_NAMES = {
|
||||||
|
"classLoaderName",
|
||||||
|
"moduleName",
|
||||||
|
"moduleVersion",
|
||||||
|
"className",
|
||||||
|
"methodName",
|
||||||
|
"fileName",
|
||||||
|
"lineNumber",
|
||||||
|
"nativeMethod",
|
||||||
|
};
|
||||||
|
|
||||||
|
static final String[] STE_V5_ITEM_NAMES = Arrays.copyOfRange(STE_ITEM_NAMES, 3, 8);
|
||||||
|
|
||||||
|
static final OpenType[] STE_V5_ITEM_TYPES = {
|
||||||
|
SimpleType.STRING,
|
||||||
|
SimpleType.STRING,
|
||||||
|
SimpleType.STRING,
|
||||||
|
SimpleType.INTEGER,
|
||||||
|
SimpleType.BOOLEAN
|
||||||
|
};
|
||||||
|
|
||||||
|
static final String[] LOCK_INFO_ITEM_NAMES = {
|
||||||
|
"className",
|
||||||
|
"identityHashCode",
|
||||||
|
};
|
||||||
|
|
||||||
|
static final String[] LOCKED_MONITORS_ITEM_NAMES = {
|
||||||
|
LOCK_INFO_ITEM_NAMES[0],
|
||||||
|
LOCK_INFO_ITEM_NAMES[1],
|
||||||
|
"lockedStackFrame",
|
||||||
|
"lockedStackDepth",
|
||||||
|
};
|
||||||
|
|
||||||
|
static final Object[] V5_VALUES = {
|
||||||
|
Long.valueOf(100),
|
||||||
|
"FooThread",
|
||||||
|
"RUNNABLE",
|
||||||
|
Long.valueOf(200),
|
||||||
|
Long.valueOf(10),
|
||||||
|
Long.valueOf(300),
|
||||||
|
Long.valueOf(20),
|
||||||
|
lockName,
|
||||||
|
Long.valueOf(99),
|
||||||
|
"BarThread",
|
||||||
|
new CompositeData[] { makeStackTraceElement() },
|
||||||
|
Boolean.valueOf(false),
|
||||||
|
Boolean.valueOf(false),
|
||||||
|
};
|
||||||
|
|
||||||
|
static final Object[] V6_VALUES = {
|
||||||
|
makeLockInfo(),
|
||||||
|
makeLockedMonitors(),
|
||||||
|
makeLockedSynchronizers(),
|
||||||
|
};
|
||||||
|
|
||||||
|
static final Object[] V9_VALUES = {
|
||||||
|
Boolean.valueOf(true),
|
||||||
|
Thread.NORM_PRIORITY,
|
||||||
|
};
|
||||||
|
|
||||||
|
static final String[] ITEM_NAMES =
|
||||||
|
concat(V5_ITEM_NAMES, V6_ITEM_NAMES, V9_ITEM_NAMES).toArray(String[]::new);
|
||||||
|
|
||||||
|
static final OpenType[] ITEM_TYPES =
|
||||||
|
concat(V5_ITEM_TYPES, V6_ITEM_TYPES, V9_ITEM_TYPES).toArray(OpenType[]::new);
|
||||||
|
|
||||||
|
static final Object[] VALUES =
|
||||||
|
concat(V5_VALUES, V6_VALUES, V9_VALUES).toArray(Object[]::new);
|
||||||
|
|
||||||
|
static <T> Stream<T> concat(T[]... streams) {
|
||||||
|
return Stream.of(streams).flatMap(a -> Arrays.stream(a));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String[] badItemNames = {
|
|
||||||
"threadId",
|
|
||||||
"threadName",
|
|
||||||
"threadState",
|
|
||||||
"blockedTime",
|
|
||||||
"blockedCount",
|
|
||||||
"waitedTime",
|
|
||||||
"waitedCount",
|
|
||||||
"lockName",
|
|
||||||
"lockOwnerId",
|
|
||||||
"lockOwnerName",
|
|
||||||
"BadStackTrace", // bad item name
|
|
||||||
"suspended",
|
|
||||||
"inNative",
|
|
||||||
"lockInfo",
|
|
||||||
"daemon",
|
|
||||||
"priority",
|
|
||||||
};
|
|
||||||
private static final OpenType[] badItemTypes = {
|
|
||||||
SimpleType.LONG,
|
|
||||||
SimpleType.STRING,
|
|
||||||
SimpleType.STRING,
|
|
||||||
SimpleType.LONG,
|
|
||||||
SimpleType.LONG,
|
|
||||||
SimpleType.LONG,
|
|
||||||
SimpleType.LONG,
|
|
||||||
SimpleType.STRING,
|
|
||||||
SimpleType.LONG,
|
|
||||||
SimpleType.STRING,
|
|
||||||
SimpleType.LONG, // bad type
|
|
||||||
SimpleType.BOOLEAN,
|
|
||||||
SimpleType.BOOLEAN,
|
|
||||||
SimpleType.LONG, // bad type
|
|
||||||
SimpleType.BOOLEAN,
|
|
||||||
SimpleType.INTEGER,
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,25 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2015, 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
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -6,6 +28,7 @@ import javax.management.openmbean.CompositeDataSupport;
|
||||||
import javax.management.openmbean.CompositeType;
|
import javax.management.openmbean.CompositeType;
|
||||||
import javax.management.openmbean.OpenType;
|
import javax.management.openmbean.OpenType;
|
||||||
import javax.management.openmbean.SimpleType;
|
import javax.management.openmbean.SimpleType;
|
||||||
|
|
||||||
import sun.management.StackTraceElementCompositeData;
|
import sun.management.StackTraceElementCompositeData;
|
||||||
|
|
||||||
import org.testng.annotations.*;
|
import org.testng.annotations.*;
|
||||||
|
@ -14,6 +37,7 @@ import static org.testng.Assert.*;
|
||||||
/*
|
/*
|
||||||
* @test
|
* @test
|
||||||
* @bug 8139587
|
* @bug 8139587
|
||||||
|
* @modules java.management/sun.management
|
||||||
* @summary Check backward compatibility of StackTraceElementCompositeData
|
* @summary Check backward compatibility of StackTraceElementCompositeData
|
||||||
* @author Jaroslav Bachorik
|
* @author Jaroslav Bachorik
|
||||||
*
|
*
|
||||||
|
@ -22,21 +46,33 @@ import static org.testng.Assert.*;
|
||||||
|
|
||||||
public class CompatibilityTest {
|
public class CompatibilityTest {
|
||||||
private static CompositeType compositeTypeV6;
|
private static CompositeType compositeTypeV6;
|
||||||
private static Map<String, Object> itemsV6;
|
private static CompositeType compositeType;
|
||||||
private static CompositeData compositeDataV6;
|
|
||||||
|
// Attribute names
|
||||||
|
private static final String CLASS_LOADER_NAME = "classLoaderName";
|
||||||
|
private static final String MODULE_NAME = "moduleName";
|
||||||
|
private static final String MODULE_VERSION = "moduleVersion";
|
||||||
|
private static final String CLASS_NAME = "className";
|
||||||
|
private static final String METHOD_NAME = "methodName";
|
||||||
|
private static final String FILE_NAME = "fileName";
|
||||||
|
private static final String LINE_NUMBER = "lineNumber";
|
||||||
|
private static final String NATIVE_METHOD = "nativeMethod";
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void setup() throws Exception {
|
public static void setup() throws Exception {
|
||||||
|
String[] v6Names = {
|
||||||
|
CLASS_NAME, METHOD_NAME, FILE_NAME, NATIVE_METHOD, LINE_NUMBER
|
||||||
|
};
|
||||||
|
String[] names = {
|
||||||
|
CLASS_LOADER_NAME, MODULE_NAME, MODULE_VERSION,
|
||||||
|
CLASS_NAME, METHOD_NAME, FILE_NAME, NATIVE_METHOD, LINE_NUMBER
|
||||||
|
};
|
||||||
compositeTypeV6 = new CompositeType(
|
compositeTypeV6 = new CompositeType(
|
||||||
StackTraceElement.class.getName(),
|
StackTraceElement.class.getName(),
|
||||||
"StackTraceElement",
|
"StackTraceElement",
|
||||||
new String[]{
|
v6Names,
|
||||||
"className", "methodName", "fileName", "nativeMethod", "lineNumber"
|
v6Names,
|
||||||
},
|
new OpenType[] {
|
||||||
new String[]{
|
|
||||||
"className", "methodName", "fileName", "nativeMethod", "lineNumber"
|
|
||||||
},
|
|
||||||
new OpenType[]{
|
|
||||||
SimpleType.STRING,
|
SimpleType.STRING,
|
||||||
SimpleType.STRING,
|
SimpleType.STRING,
|
||||||
SimpleType.STRING,
|
SimpleType.STRING,
|
||||||
|
@ -44,20 +80,52 @@ public class CompatibilityTest {
|
||||||
SimpleType.INTEGER
|
SimpleType.INTEGER
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
compositeType = new CompositeType(
|
||||||
|
StackTraceElement.class.getName(),
|
||||||
|
"StackTraceElement",
|
||||||
|
names,
|
||||||
|
names,
|
||||||
|
new OpenType[] {
|
||||||
|
SimpleType.STRING,
|
||||||
|
SimpleType.STRING,
|
||||||
|
SimpleType.STRING,
|
||||||
|
SimpleType.STRING,
|
||||||
|
SimpleType.STRING,
|
||||||
|
SimpleType.STRING,
|
||||||
|
SimpleType.BOOLEAN,
|
||||||
|
SimpleType.INTEGER
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
itemsV6 = new HashMap<>();
|
private static CompositeData makeCompositeDataV6() throws Exception {
|
||||||
itemsV6.put("className", "MyClass");
|
Map<String, Object> itemsV6 = new HashMap<>();
|
||||||
itemsV6.put("methodName", "myMethod");
|
itemsV6.put(CLASS_NAME, "MyClass");
|
||||||
itemsV6.put("fileName", "MyClass.java");
|
itemsV6.put(METHOD_NAME, "myMethod");
|
||||||
itemsV6.put("nativeMethod", false);
|
itemsV6.put(FILE_NAME, "MyClass.java");
|
||||||
itemsV6.put("lineNumber", 123);
|
itemsV6.put(NATIVE_METHOD, false);
|
||||||
|
itemsV6.put(LINE_NUMBER, 123);
|
||||||
|
|
||||||
compositeDataV6 = new CompositeDataSupport(compositeTypeV6, itemsV6);
|
return new CompositeDataSupport(compositeTypeV6, itemsV6);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static CompositeData makeCompositeData() throws Exception {
|
||||||
|
Map<String, Object> items = new HashMap<>();
|
||||||
|
items.put(CLASS_LOADER_NAME, "app");
|
||||||
|
items.put(MODULE_NAME, "m");
|
||||||
|
items.put(MODULE_VERSION, "1.0");
|
||||||
|
items.put(CLASS_NAME, "MyClass");
|
||||||
|
items.put(METHOD_NAME, "myMethod");
|
||||||
|
items.put(FILE_NAME, "MyClass.java");
|
||||||
|
items.put(NATIVE_METHOD, false);
|
||||||
|
items.put(LINE_NUMBER, 123);
|
||||||
|
|
||||||
|
return new CompositeDataSupport(compositeType, items);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testV6Compatibility() throws Exception {
|
public void testV6Compatibility() throws Exception {
|
||||||
StackTraceElement ste = StackTraceElementCompositeData.from(compositeDataV6);
|
StackTraceElement ste = StackTraceElementCompositeData.from(makeCompositeDataV6());
|
||||||
|
|
||||||
assertNotNull(ste);
|
assertNotNull(ste);
|
||||||
assertEquals(ste.getClassName(), "MyClass");
|
assertEquals(ste.getClassName(), "MyClass");
|
||||||
|
@ -69,5 +137,22 @@ public class CompatibilityTest {
|
||||||
assertNull(ste.getModuleName());
|
assertNull(ste.getModuleName());
|
||||||
assertNull(ste.getModuleVersion());
|
assertNull(ste.getModuleVersion());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() throws Exception {
|
||||||
|
StackTraceElement ste = StackTraceElementCompositeData.from(makeCompositeData());
|
||||||
|
|
||||||
|
assertNotNull(ste);
|
||||||
|
|
||||||
|
assertEquals(ste.getModuleName(), "m");
|
||||||
|
assertEquals(ste.getModuleVersion(), "1.0");
|
||||||
|
assertEquals(ste.getClassLoaderName(), "app");
|
||||||
|
|
||||||
|
assertEquals(ste.getClassName(), "MyClass");
|
||||||
|
assertEquals(ste.getMethodName(), "myMethod");
|
||||||
|
assertEquals(ste.getFileName(), "MyClass.java");
|
||||||
|
assertEquals(ste.isNativeMethod(), false);
|
||||||
|
assertEquals(ste.getLineNumber(), 123);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue