1 /* MonitorInfo.java - Information on a monitor lock. 2 Copyright (C) 2006 Free Software Foundation 3 4 This file is part of GNU Classpath. 5 6 GNU Classpath is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2, or (at your option) 9 any later version. 10 11 GNU Classpath is distributed in the hope that it will be useful, but 12 WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GNU Classpath; see the file COPYING. If not, write to the 18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19 02110-1301 USA. 20 21 Linking this library statically or dynamically with other modules is 22 making a combined work based on this library. Thus, the terms and 23 conditions of the GNU General Public License cover the whole 24 combination. 25 26 As a special exception, the copyright holders of this library give you 27 permission to link this library with independent modules to produce an 28 executable, regardless of the license terms of these independent 29 modules, and to copy and distribute the resulting executable under 30 terms of your choice, provided that you also meet, for each linked 31 independent module, the terms and conditions of the license of that 32 module. An independent module is a module which is not derived from 33 or based on this library. If you modify this library, you may extend 34 this exception to your version of the library, but you are not 35 obligated to do so. If you do not wish to do so, delete this 36 exception statement from your version. */ 37 38 package java.lang.management; 39 40 import javax.management.openmbean.CompositeData; 41 import javax.management.openmbean.CompositeType; 42 import javax.management.openmbean.SimpleType; 43 44 /** 45 * Provides information on a monitor lock held by a thread. 46 * A monitor lock is obtained when a thread enters a synchronized 47 * block or method. 48 * 49 * @author Andrew John Hughes (gnu_andrew@member.fsf.org) 50 * @since 1.6 51 */ 52 public class MonitorInfo 53 extends LockInfo 54 { 55 56 /** 57 * The stack depth at which the lock was obtained. 58 */ 59 private int stackDepth; 60 61 /** 62 * The stack frame at which the lock was obtained. 63 */ 64 private StackTraceElement stackFrame; 65 66 /** 67 * Constructs a new {@link MonitorInfo} using the specified 68 * lock class name and identity hash code, and the given 69 * stack depth and frame. 70 * 71 * @param className the class name of the lock object. 72 * @param identityHashCode the identity hash code of the lock object. 73 * @param stackDepth the depth of the stack at which the lock 74 * was obtained. 75 * @param stackFrame the frame of the stack at which the lock was 76 * obtained. 77 * @throws IllegalArgumentException if the stack depth and frame are 78 * inconsistent i.e. the frame is 79 * <code>null</code> but the depth is 80 * ≥ 0, or the frame is not 81 * <code>null</code> but the depth is 82 * < 0. 83 */ MonitorInfo(String className, int identityHashCode, int stackDepth, StackTraceElement stackFrame)84 public MonitorInfo(String className, int identityHashCode, int stackDepth, 85 StackTraceElement stackFrame) 86 { 87 super(className, identityHashCode); 88 if (stackFrame == null && stackDepth >= 0) 89 throw new IllegalArgumentException("The stack frame is null, but the " + 90 "stack depth is greater than or equal " + 91 "to zero."); 92 if (stackFrame != null && stackDepth < 0) 93 throw new IllegalArgumentException("The stack frame is not null, but the " + 94 "stack depth is less than zero."); 95 this.stackDepth = stackDepth; 96 this.stackFrame = stackFrame; 97 } 98 99 /** 100 * <p> 101 * Returns a {@link MonitorInfo} instance using the values 102 * given in the supplied 103 * {@link javax.management.openmbean.CompositeData} object. 104 * The composite data instance should contain the following 105 * attributes with the specified types: 106 * </p> 107 * <table> 108 * <th><td>Name</td><td>Type</td></th> 109 * <tr><td>className</td><td>java.lang.String</td></tr> 110 * <tr><td>identityHashCode</td><td>java.lang.Integer</td></tr> 111 * <tr><td>lockedStackDepth</td><td>java.lang.Integer</td></tr> 112 * <tr><td>lockedStackFrame</td><td>javax.management.openmbean.CompositeData 113 * </td></tr> 114 * </table> 115 * <p> 116 * The stack trace is further described as: 117 * </p> 118 * <table> 119 * <th><td>Name</td><td>Type</td></th> 120 * <tr><td>className</td><td>java.lang.String</td></tr> 121 * <tr><td>methodName</td><td>java.lang.String</td></tr> 122 * <tr><td>fileName</td><td>java.lang.String</td></tr> 123 * <tr><td>lineNumber</td><td>java.lang.Integer</td></tr> 124 * <tr><td>nativeMethod</td><td>java.lang.Boolean</td></tr> 125 * </table> 126 * 127 * @param data the composite data structure to take values from. 128 * @return a new instance containing the values from the 129 * composite data structure, or <code>null</code> 130 * if the data structure was also <code>null</code>. 131 * @throws IllegalArgumentException if the composite data structure 132 * does not match the structure 133 * outlined above. 134 */ from(CompositeData data)135 public static MonitorInfo from(CompositeData data) 136 { 137 if (data == null) 138 return null; 139 CompositeType type = data.getCompositeType(); 140 ThreadInfo.checkAttribute(type, "ClassName", SimpleType.STRING); 141 ThreadInfo.checkAttribute(type, "IdentityHashCode", SimpleType.INTEGER); 142 ThreadInfo.checkAttribute(type, "LockedStackDepth", SimpleType.INTEGER); 143 ThreadInfo.checkAttribute(type, "LockedStackFrame", 144 ThreadInfo.getStackTraceType()); 145 CompositeData frame = (CompositeData) data.get("LockedStackFrame"); 146 return new MonitorInfo((String) data.get("ClassName"), 147 (Integer) data.get("IdentityHashCode"), 148 (Integer) data.get("LockedStackDepth"), 149 new StackTraceElement((String) frame.get("ClassName"), 150 (String) frame.get("MethodName"), 151 (String) frame.get("FileName"), 152 (Integer) frame.get("LineNumber"))); 153 } 154 155 /** 156 * Returns the depth of the stack at which the lock was obtained. 157 * This works as an index into the array returned by 158 * {@link ThreadInfo#getStackTrace()}. 159 * 160 * @return the depth of the stack at which the lock was obtained, 161 * or a negative number if this information is unavailable. 162 */ getLockedStackDepth()163 public int getLockedStackDepth() 164 { 165 return stackDepth; 166 } 167 168 /** 169 * Returns the stack frame at which the lock was obtained. 170 * 171 * @return the stack frame at which the lock was obtained, 172 * or <code>null</code> if this informati0on is unavailable. 173 */ getLockedStackFrame()174 public StackTraceElement getLockedStackFrame() 175 { 176 return stackFrame; 177 } 178 179 } 180