1 /* 2 * Copyright (c) 2004, 2005, 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. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @bug 4982289 27 * @summary Test ThreadInfo.from to return a valid 28 * ThreadInfo object. Or throw exception if 29 * the input CompositeData is invalid. 30 * @author Mandy Chung 31 * 32 * @compile OpenTypeConverter.java 33 * @build ThreadInfoCompositeData 34 * @run main ThreadInfoCompositeData 35 */ 36 37 import javax.management.openmbean.*; 38 import java.lang.management.LockInfo; 39 import java.lang.management.MonitorInfo; 40 import java.lang.management.ThreadInfo; 41 42 public class ThreadInfoCompositeData { 43 private static StackTraceElement[] ste = new StackTraceElement[1]; 44 private static CompositeData[] steCD = new CompositeData[1]; 45 private static String lockClassName = "myClass"; 46 private static int lockIdentityHashCode = 123456; 47 private static String lockName = lockClassName + '@' + 48 Integer.toHexString(lockIdentityHashCode); 49 private static LockInfo lockInfo = 50 new LockInfo(lockClassName, lockIdentityHashCode); 51 52 public static void main(String[] argv) throws Exception { 53 // A valid CompositeData is passed to ThreadInfo 54 createGoodCompositeData(); 55 // A valid CompositeData for JDK 5.0 ThreadInfo 56 // is passed to ThreadInfo 57 createV5ThreadInfo(); 58 // An invalid CompositeData is passed to ThreadInfo.from() 59 badNameCompositeData(); 60 badTypeCompositeData(); 61 System.out.println("Test passed"); 62 } 63 64 public static void createGoodCompositeData() throws Exception { 65 CompositeType ct = 66 new CompositeType("MyCompositeType", 67 "CompositeType for ThreadInfo", 68 validItemNames, 69 validItemNames, 70 validItemTypes); 71 CompositeData cd = 72 new CompositeDataSupport(ct, 73 validItemNames, 74 values); 75 ThreadInfo info = ThreadInfo.from(cd); 76 checkThreadInfo(info); 77 } 78 79 public static void createV5ThreadInfo() throws Exception { 80 String[] v5ItemNames = new String[NUM_V5_ATTS]; 81 OpenType[] v5ItemTypes = new OpenType[NUM_V5_ATTS]; 82 Object[] v5ItemValues = new Object[NUM_V5_ATTS]; 83 for (int i = 0; i < NUM_V5_ATTS; i++) { 84 v5ItemNames[i] = validItemNames[i]; 85 v5ItemTypes[i] = validItemTypes[i]; 86 v5ItemValues[i] = values[i]; 87 } 88 CompositeType ct = 89 new CompositeType("MyCompositeType", 90 "CompositeType for JDK 5.0 ThreadInfo", 91 v5ItemNames, 92 v5ItemNames, 93 v5ItemTypes); 94 CompositeData cd = 95 new CompositeDataSupport(ct, 96 v5ItemNames, 97 v5ItemValues); 98 ThreadInfo info = ThreadInfo.from(cd); 99 checkThreadInfo(info); 100 } 101 102 static void checkThreadInfo(ThreadInfo info) throws Exception { 103 if (info.getThreadId() != ((Long) values[THREAD_ID]).longValue()) { 104 throw new RuntimeException("Thread Id = " + info.getThreadId() + 105 " expected = " + values[THREAD_ID]); 106 } 107 if (!info.getThreadName().equals(values[THREAD_NAME])) { 108 throw new RuntimeException("Thread Name = " + 109 info.getThreadName() + " expected = " + values[THREAD_NAME]); 110 } 111 if (info.getThreadState() != Thread.State.RUNNABLE) { 112 throw new RuntimeException("Thread Name = " + 113 info.getThreadName() + " expected = " + Thread.State.RUNNABLE); 114 } 115 if (info.getBlockedTime() != ((Long) values[BLOCKED_TIME]).longValue()) { 116 throw new RuntimeException("blocked time = " + 117 info.getBlockedTime() + 118 " expected = " + values[BLOCKED_TIME]); 119 } 120 if (info.getBlockedCount() != ((Long) values[BLOCKED_COUNT]).longValue()) { 121 throw new RuntimeException("blocked count = " + 122 info.getBlockedCount() + 123 " expected = " + values[BLOCKED_COUNT]); 124 } 125 if (info.getWaitedTime() != ((Long) values[WAITED_TIME]).longValue()) { 126 throw new RuntimeException("waited time = " + 127 info.getWaitedTime() + 128 " expected = " + values[WAITED_TIME]); 129 } 130 if (info.getWaitedCount() != ((Long) values[WAITED_COUNT]).longValue()) { 131 throw new RuntimeException("waited count = " + 132 info.getWaitedCount() + 133 " expected = " + values[WAITED_COUNT]); 134 } 135 if (!info.getLockName().equals(values[LOCK_NAME])) { 136 throw new RuntimeException("Lock Name = " + 137 info.getLockName() + " expected = " + values[LOCK_NAME]); 138 } 139 if (info.getLockOwnerId() != 140 ((Long) values[LOCK_OWNER_ID]).longValue()) { 141 throw new RuntimeException( 142 "LockOwner Id = " + info.getLockOwnerId() + 143 " expected = " + values[LOCK_OWNER_ID]); 144 } 145 if (!info.getLockOwnerName().equals(values[LOCK_OWNER_NAME])) { 146 throw new RuntimeException("LockOwner Name = " + 147 info.getLockOwnerName() + " expected = " + 148 values[LOCK_OWNER_NAME]); 149 } 150 if (!values[DAEMON].equals(info.isDaemon())) { 151 throw new RuntimeException("Daemon = " + 152 info.isDaemon() + " expected = " + 153 values[DAEMON]); 154 } 155 156 checkStackTrace(info.getStackTrace()); 157 158 checkLockInfo(info.getLockInfo()); 159 } 160 161 private static void checkStackTrace(StackTraceElement[] s) 162 throws Exception { 163 if (ste.length != s.length) { 164 throw new RuntimeException("Stack Trace length = " + 165 s.length + " expected = " + ste.length); 166 } 167 168 StackTraceElement s1 = ste[0]; 169 StackTraceElement s2 = s[0]; 170 171 if (!s1.getClassName().equals(s2.getClassName())) { 172 throw new RuntimeException("Class name = " + 173 s2.getClassName() + " expected = " + s1.getClassName()); 174 } 175 if (!s1.getMethodName().equals(s2.getMethodName())) { 176 throw new RuntimeException("Method name = " + 177 s2.getMethodName() + " expected = " + s1.getMethodName()); 178 } 179 if (!s1.getFileName().equals(s2.getFileName())) { 180 throw new RuntimeException("File name = " + 181 s2.getFileName() + " expected = " + s1.getFileName()); 182 } 183 if (s1.getLineNumber() != s2.getLineNumber()) { 184 throw new RuntimeException("Line number = " + 185 s2.getLineNumber() + " expected = " + s1.getLineNumber()); 186 } 187 } 188 189 private static void checkLockInfo(LockInfo li) 190 throws Exception { 191 if (!li.getClassName().equals(lockInfo.getClassName())) { 192 throw new RuntimeException("Class Name = " + 193 li.getClassName() + " expected = " + lockInfo.getClassName()); 194 } 195 if (li.getIdentityHashCode() != lockInfo.getIdentityHashCode()) { 196 throw new RuntimeException("Class Name = " + 197 li.getIdentityHashCode() + " expected = " + 198 lockInfo.getIdentityHashCode()); 199 } 200 } 201 202 public static void badNameCompositeData() throws Exception { 203 CompositeType ct = 204 new CompositeType("MyCompositeType", 205 "CompositeType for ThreadInfo", 206 badItemNames, 207 badItemNames, 208 validItemTypes); 209 CompositeData cd = 210 new CompositeDataSupport(ct, 211 badItemNames, 212 values); 213 214 try { 215 ThreadInfo info = ThreadInfo.from(cd); 216 } catch (IllegalArgumentException e) { 217 System.out.println("Expected exception: " + 218 e.getMessage()); 219 return; 220 } 221 throw new RuntimeException( 222 "IllegalArgumentException not thrown"); 223 } 224 225 public static void badTypeCompositeData() throws Exception { 226 CompositeType ct = 227 new CompositeType("MyCompositeType", 228 "CompositeType for ThreadInfo", 229 validItemNames, 230 validItemNames, 231 badItemTypes); 232 233 // patch values[STACK_TRACE] to Long 234 values[STACK_TRACE] = new Long(1000); 235 values[LOCK_INFO] = new Long(1000); 236 CompositeData cd = 237 new CompositeDataSupport(ct, 238 validItemNames, 239 values); 240 241 try { 242 ThreadInfo info = ThreadInfo.from(cd); 243 } catch (IllegalArgumentException e) { 244 System.out.println("Expected exception: " + 245 e.getMessage()); 246 return; 247 } 248 throw new RuntimeException( 249 "IllegalArgumentException not thrown"); 250 } 251 252 private static final int THREAD_ID = 0; 253 private static final int THREAD_NAME = 1; 254 private static final int THREAD_STATE = 2; 255 private static final int BLOCKED_TIME = 3; 256 private static final int BLOCKED_COUNT = 4; 257 private static final int WAITED_TIME = 5; 258 private static final int WAITED_COUNT = 6; 259 private static final int LOCK_NAME = 7; 260 private static final int LOCK_OWNER_ID = 8; 261 private static final int LOCK_OWNER_NAME = 9; 262 private static final int STACK_TRACE = 10; 263 private static final int SUSPENDED = 11; 264 private static final int IN_NATIVE = 12; 265 private static final int NUM_V5_ATTS = 13; 266 // JDK 6.0 ThreadInfo attributes 267 private static final int LOCK_INFO = 13; 268 // JDK 9.0 ThreadInfo attributes 269 private static final int DAEMON = 14; 270 private static final int PRIORITY = 15; 271 272 private static final String[] validItemNames = { 273 "threadId", 274 "threadName", 275 "threadState", 276 "blockedTime", 277 "blockedCount", 278 "waitedTime", 279 "waitedCount", 280 "lockName", 281 "lockOwnerId", 282 "lockOwnerName", 283 "stackTrace", 284 "suspended", 285 "inNative", 286 "lockInfo", 287 "daemon", 288 "priority", 289 }; 290 291 private static OpenType[] validItemTypes = { 292 SimpleType.LONG, 293 SimpleType.STRING, 294 SimpleType.STRING, 295 SimpleType.LONG, 296 SimpleType.LONG, 297 SimpleType.LONG, 298 SimpleType.LONG, 299 SimpleType.STRING, 300 SimpleType.LONG, 301 SimpleType.STRING, 302 null, // ArrayType for StackTraceElement[] 303 SimpleType.BOOLEAN, 304 SimpleType.BOOLEAN, 305 null, // CompositeType for LockInfo 306 SimpleType.BOOLEAN, 307 SimpleType.INTEGER, 308 }; 309 310 private static Object[] values = { 311 new Long(100), 312 "FooThread", 313 "RUNNABLE", 314 new Long(200), 315 new Long(10), 316 new Long(300), 317 new Long(20), 318 lockName, 319 new Long(99), 320 "BarThread", 321 steCD, 322 new Boolean(false), 323 new Boolean(false), 324 null, // To be initialized to lockInfoCD 325 new Boolean(false), 326 Thread.NORM_PRIORITY, 327 }; 328 329 private static final String[] steItemNames = { 330 "className", 331 "methodName", 332 "fileName", 333 "lineNumber", 334 "nativeMethod", 335 }; 336 337 private static final String[] lockInfoItemNames = { 338 "className", 339 "identityHashCode", 340 }; 341 342 static { 343 // create stack trace element 344 ste[0] = new StackTraceElement("FooClass", "getFoo", "Foo.java", 100); 345 346 // initialize the ste[0] and values and validItemTypes 347 try { 348 CompositeType steCType = (CompositeType) 349 OpenTypeConverter.toOpenType(StackTraceElement.class); 350 validItemTypes[STACK_TRACE] = new ArrayType(1, steCType); 351 352 final Object[] steValue = { 353 ste[0].getClassName(), 354 ste[0].getMethodName(), 355 ste[0].getFileName(), 356 new Integer(ste[0].getLineNumber()), 357 new Boolean(ste[0].isNativeMethod()), 358 }; 359 360 steCD[0] = 361 new CompositeDataSupport(steCType, 362 steItemNames, 363 steValue); 364 365 CompositeType lockInfoCType = (CompositeType) 366 OpenTypeConverter.toOpenType(LockInfo.class); 367 validItemTypes[LOCK_INFO] = lockInfoCType; 368 369 final Object[] lockInfoValue = { 370 lockInfo.getClassName(), 371 lockInfo.getIdentityHashCode(), 372 }; 373 374 values[LOCK_INFO] = 375 new CompositeDataSupport(lockInfoCType, 376 lockInfoItemNames, 377 lockInfoValue); 378 } catch (Exception e) { 379 throw new RuntimeException(e); 380 } 381 } 382 383 private static final String[] badItemNames = { 384 "threadId", 385 "threadName", 386 "threadState", 387 "blockedTime", 388 "blockedCount", 389 "waitedTime", 390 "waitedCount", 391 "lockName", 392 "lockOwnerId", 393 "lockOwnerName", 394 "BadStackTrace", // bad item name 395 "suspended", 396 "inNative", 397 "lockInfo", 398 "daemon", 399 "priority", 400 }; 401 private static final OpenType[] badItemTypes = { 402 SimpleType.LONG, 403 SimpleType.STRING, 404 SimpleType.STRING, 405 SimpleType.LONG, 406 SimpleType.LONG, 407 SimpleType.LONG, 408 SimpleType.LONG, 409 SimpleType.STRING, 410 SimpleType.LONG, 411 SimpleType.STRING, 412 SimpleType.LONG, // bad type 413 SimpleType.BOOLEAN, 414 SimpleType.BOOLEAN, 415 SimpleType.LONG, // bad type 416 SimpleType.BOOLEAN, 417 SimpleType.INTEGER, 418 }; 419 420 }