1 /*
2 * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package java.lang.management;
27
28 import javax.management.openmbean.CompositeData;
29 import sun.management.MonitorInfoCompositeData;
30
31 /**
32 * Information about an object monitor lock. An object monitor is locked
33 * when entering a synchronization block or method on that object.
34 *
35 * <h3>MXBean Mapping</h3>
36 * {@code MonitorInfo} is mapped to a {@link CompositeData CompositeData}
37 * with attributes as specified in
38 * the {@link #from from} method.
39 *
40 * @author Mandy Chung
41 * @since 1.6
42 */
43 public class MonitorInfo extends LockInfo {
44
45 private int stackDepth;
46 private StackTraceElement stackFrame;
47
48 /**
49 * Construct a {@code MonitorInfo} object.
50 *
51 * @param className the fully qualified name of the class of the lock object.
52 * @param identityHashCode the {@link System#identityHashCode
53 * identity hash code} of the lock object.
54 * @param stackDepth the depth in the stack trace where the object monitor
55 * was locked.
56 * @param stackFrame the stack frame that locked the object monitor.
57 * @throws IllegalArgumentException if
58 * {@code stackDepth} ≥ 0 but {@code stackFrame} is {@code null},
59 * or {@code stackDepth} < 0 but {@code stackFrame} is not
60 * {@code null}.
61 */
62 public MonitorInfo(String className,
63 int identityHashCode,
64 int stackDepth,
65 StackTraceElement stackFrame) {
66 super(className, identityHashCode);
67 if (stackDepth >= 0 && stackFrame == null) {
68 throw new IllegalArgumentException("Parameter stackDepth is " +
69 stackDepth + " but stackFrame is null");
70 }
71 if (stackDepth < 0 && stackFrame != null) {
72 throw new IllegalArgumentException("Parameter stackDepth is " +
73 stackDepth + " but stackFrame is not null");
74 }
75 this.stackDepth = stackDepth;
76 this.stackFrame = stackFrame;
77 }
78
79 /**
80 * Returns the depth in the stack trace where the object monitor
81 * was locked. The depth is the index to the {@code StackTraceElement}
82 * array returned in the {@link ThreadInfo#getStackTrace} method.
83 *
84 * @return the depth in the stack trace where the object monitor
85 * was locked, or a negative number if not available.
86 */
87 public int getLockedStackDepth() {
88 return stackDepth;
89 }
90
91 /**
92 * Returns the stack frame that locked the object monitor.
93 *
94 * @return {@code StackTraceElement} that locked the object monitor,
95 * or {@code null} if not available.
96 */
97 public StackTraceElement getLockedStackFrame() {
98 return stackFrame;
99 }
100
101 /**
102 * Returns a {@code MonitorInfo} object represented by the
103 * given {@code CompositeData}.
104 * The given {@code CompositeData} must contain the following attributes
105 * as well as the attributes specified in the
106 * <a href="LockInfo.html#MappedType">
107 * mapped type</a> for the {@link LockInfo} class:
108 * <table class="striped" style="margin-left:2em">
109 * <caption style="display:none">The attributes and their types the given CompositeData contains</caption>
110 * <thead>
111 * <tr>
112 * <th scope="col">Attribute Name</th>
113 * <th scope="col">Type</th>
114 * </tr>
115 * </thead>
116 * <tbody style="text-align:left">
117 * <tr>
118 * <th scope="row">lockedStackFrame</th>
119 * <td><a href="ThreadInfo.html#stackTraceElement">
120 * {@code CompositeData} for {@code StackTraceElement}</a> as specified
121 * in {@link ThreadInfo#from(CompositeData)} method.
122 * </td>
123 * </tr>
124 * <tr>
125 * <th scope="row">lockedStackDepth</th>
126 * <td>{@code java.lang.Integer}</td>
127 * </tr>
128 * </tbody>
129 * </table>
130 *
131 * @param cd {@code CompositeData} representing a {@code MonitorInfo}
132 *
133 * @throws IllegalArgumentException if {@code cd} does not
134 * represent a {@code MonitorInfo} with the attributes described
135 * above.
136 *
137 * @return a {@code MonitorInfo} object represented
138 * by {@code cd} if {@code cd} is not {@code null};
139 * {@code null} otherwise.
140 */
141 public static MonitorInfo from(CompositeData cd) {
142 if (cd == null) {
143 return null;
144 }
145
146 if (cd instanceof MonitorInfoCompositeData) {
147 return ((MonitorInfoCompositeData) cd).getMonitorInfo();
148 } else {
149 MonitorInfoCompositeData.validateCompositeData(cd);
150 String className = MonitorInfoCompositeData.getClassName(cd);
151 int identityHashCode = MonitorInfoCompositeData.getIdentityHashCode(cd);
152 int stackDepth = MonitorInfoCompositeData.getLockedStackDepth(cd);
153 StackTraceElement stackFrame = MonitorInfoCompositeData.getLockedStackFrame(cd);
154 return new MonitorInfo(className,
155 identityHashCode,
156 stackDepth,
157 stackFrame);
158 }
159 }
160
161 }
162