1 /* 2 * Copyright (c) 2004, 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. 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 8198253 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 * @build ThreadInfoCompositeData OpenTypeConverter 33 * @run main ThreadInfoCompositeData 34 */ 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 import java.util.Arrays; 42 import java.util.Objects; 43 import java.util.stream.Stream; 44 45 public class ThreadInfoCompositeData { 46 private static String lockClassName = "myClass"; 47 private static int lockIdentityHashCode = 123456; 48 private static String lockName = lockClassName + '@' + 49 Integer.toHexString(lockIdentityHashCode); 50 private static LockInfo lockInfo = 51 new LockInfo(lockClassName, lockIdentityHashCode); 52 53 public static void main(String[] argv) throws Exception { 54 // A valid CompositeData is passed to ThreadInfo 55 createGoodCompositeData(); 56 // A valid CompositeData for JDK 5 ThreadInfo 57 // is passed to ThreadInfo 58 createV5ThreadInfo(); 59 // ThreadInfo of version N can accept lockedMonitors of version >= N 60 withNewMonitorInfoCompositeData(); 61 62 // An invalid CompositeData is passed to ThreadInfo.from() 63 badNameCompositeData(); 64 badTypeCompositeData(); 65 badMissingCompositeData(); 66 withV5StackTraceCompositeData(); 67 withInvalidMonitorInfoCompositeData(); 68 System.out.println("Test passed"); 69 } 70 71 public static void createGoodCompositeData() throws Exception { 72 CompositeData cd = Factory.makeThreadInfoCompositeData(); 73 ThreadInfo info = ThreadInfo.from(cd); 74 checkThreadInfo(info); 75 } 76 77 /* 78 * An invalid CompositeData with JDK 9 attributes but missing JDK 6 attributes 79 */ 80 public static void badMissingCompositeData() throws Exception { 81 CompositeData cd = Factory.makeCompositeDataMissingV6(); 82 try { 83 ThreadInfo info = ThreadInfo.from(cd); 84 throw new RuntimeException("IllegalArgumentException not thrown"); 85 } catch (IllegalArgumentException e) {} 86 } 87 88 static final StackTraceElement STE = 89 new StackTraceElement("FooClass", "getFoo", "Foo.java", 100); 90 91 92 /* 93 * Current version of ThreadInfo but an older version of StackTraceElement 94 */ 95 public static void withV5StackTraceCompositeData() throws Exception { 96 CompositeData cd = Factory.makeThreadInfoWithV5StackTrace(); 97 try { 98 ThreadInfo info = ThreadInfo.from(cd); 99 throw new RuntimeException("IllegalArgumentException not thrown"); 100 } catch (IllegalArgumentException e) {} 101 } 102 103 /* 104 * Current version of ThreadInfo but an older version of MonitorInfo 105 * and the value of "lockedStackFrame" attribute is null. 106 */ 107 public static void withInvalidMonitorInfoCompositeData() throws Exception { 108 CompositeData cd = Factory.makeThreadInfoWithIncompatibleMonitorInfo(); 109 110 // verify MonitorInfo is valid 111 CompositeData[] monitors = (CompositeData[])cd.get("lockedMonitors"); 112 CompositeData ste = (CompositeData)monitors[0].get("lockedStackFrame"); 113 if (((Integer)monitors[0].get("lockedStackDepth")) >= 0 || ste != null) { 114 throw new RuntimeException("Expected negative stack depth and null stack frame"); 115 } 116 MonitorInfo minfo = MonitorInfo.from(monitors[0]); 117 checkLockInfo(minfo); 118 if (minfo.getLockedStackFrame() != null) { 119 throw new RuntimeException("Expected null stack frame"); 120 } 121 122 try { 123 ThreadInfo info = ThreadInfo.from(cd); 124 throw new RuntimeException("IllegalArgumentException not thrown"); 125 } catch (IllegalArgumentException e) {} 126 } 127 128 /* 129 * ThreadInfo of version N can accept lockedMonitors of version >= N 130 */ 131 public static void withNewMonitorInfoCompositeData() throws Exception { 132 CompositeData cd = Factory.makeThreadInfoWithNewMonitorInfo(); 133 ThreadInfo info = ThreadInfo.from(cd); 134 checkThreadInfo(info); 135 } 136 137 /* 138 * Test CompositeData representing JDK 5 ThreadInfo 139 */ 140 public static void createV5ThreadInfo() throws Exception { 141 CompositeData cd = Factory.makeThreadInfoV5CompositeData(); 142 ThreadInfo info = ThreadInfo.from(cd); 143 checkThreadInfoV5(info); 144 } 145 146 static void checkThreadInfoV5(ThreadInfo info) { 147 Object[] values = Factory.VALUES; 148 149 if (info.getThreadId() != ((Long) values[THREAD_ID]).longValue()) { 150 throw new RuntimeException("Thread Id = " + info.getThreadId() + 151 " expected = " + values[THREAD_ID]); 152 } 153 if (!info.getThreadName().equals(values[THREAD_NAME])) { 154 throw new RuntimeException("Thread Name = " + 155 info.getThreadName() + " expected = " + values[THREAD_NAME]); 156 } 157 if (info.getThreadState() != Thread.State.RUNNABLE) { 158 throw new RuntimeException("Thread Name = " + 159 info.getThreadName() + " expected = " + Thread.State.RUNNABLE); 160 } 161 if (info.getBlockedTime() != ((Long) values[BLOCKED_TIME]).longValue()) { 162 throw new RuntimeException("blocked time = " + 163 info.getBlockedTime() + 164 " expected = " + values[BLOCKED_TIME]); 165 } 166 if (info.getBlockedCount() != ((Long) values[BLOCKED_COUNT]).longValue()) { 167 throw new RuntimeException("blocked count = " + 168 info.getBlockedCount() + 169 " expected = " + values[BLOCKED_COUNT]); 170 } 171 if (info.getWaitedTime() != ((Long) values[WAITED_TIME]).longValue()) { 172 throw new RuntimeException("waited time = " + 173 info.getWaitedTime() + 174 " expected = " + values[WAITED_TIME]); 175 } 176 if (info.getWaitedCount() != ((Long) values[WAITED_COUNT]).longValue()) { 177 throw new RuntimeException("waited count = " + 178 info.getWaitedCount() + 179 " expected = " + values[WAITED_COUNT]); 180 } 181 if (!info.getLockName().equals(values[LOCK_NAME])) { 182 throw new RuntimeException("Lock Name = " + 183 info.getLockName() + " expected = " + values[LOCK_NAME]); 184 } 185 if (info.getLockOwnerId() != 186 ((Long) values[LOCK_OWNER_ID]).longValue()) { 187 throw new RuntimeException( 188 "LockOwner Id = " + info.getLockOwnerId() + 189 " expected = " + values[LOCK_OWNER_ID]); 190 } 191 if (!info.getLockOwnerName().equals(values[LOCK_OWNER_NAME])) { 192 throw new RuntimeException("LockOwner Name = " + 193 info.getLockOwnerName() + " expected = " + 194 values[LOCK_OWNER_NAME]); 195 } 196 197 checkStackTrace(info.getStackTrace()); 198 checkLockInfo(info.getLockInfo()); 199 } 200 201 static void checkThreadInfo(ThreadInfo info) { 202 Object[] values = Factory.VALUES; 203 204 checkThreadInfoV5(info); 205 206 if (!values[DAEMON].equals(info.isDaemon())) { 207 throw new RuntimeException("Daemon = " + 208 info.isDaemon() + " expected = " + values[DAEMON]); 209 } 210 } 211 212 private static void checkStackTrace(StackTraceElement[] s) { 213 if (s.length != 1) { 214 throw new RuntimeException("Stack Trace length = " + 215 s.length + " expected = 1"); 216 } 217 218 StackTraceElement s1 = STE; 219 StackTraceElement s2 = s[0]; 220 221 // these attributes may be null 222 if (!Objects.equals(s1.getClassLoaderName(), s2.getClassLoaderName())) { 223 throw new RuntimeException("Class loader name = " + 224 s2.getClassLoaderName() + " expected = " + s1.getClassLoaderName()); 225 } 226 if (!Objects.equals(s1.getModuleName(), s2.getModuleName())) { 227 throw new RuntimeException("Module name = " + 228 s2.getModuleName() + " expected = " + s1.getModuleName()); 229 } 230 if (!Objects.equals(s1.getModuleVersion(), s2.getModuleVersion())) { 231 throw new RuntimeException("Module version = " + 232 s2.getModuleVersion() + " expected = " + s1.getModuleVersion()); 233 } 234 235 if (!s1.getClassName().equals(s2.getClassName())) { 236 throw new RuntimeException("Class name = " + 237 s2.getClassName() + " expected = " + s1.getClassName()); 238 } 239 if (!s1.getMethodName().equals(s2.getMethodName())) { 240 throw new RuntimeException("Method name = " + 241 s2.getMethodName() + " expected = " + s1.getMethodName()); 242 } 243 if (!s1.getFileName().equals(s2.getFileName())) { 244 throw new RuntimeException("File name = " + 245 s2.getFileName() + " expected = " + s1.getFileName()); 246 } 247 if (s1.getLineNumber() != s2.getLineNumber()) { 248 throw new RuntimeException("Line number = " + 249 s2.getLineNumber() + " expected = " + s1.getLineNumber()); 250 } 251 } 252 253 private static void checkLockInfo(LockInfo li) { 254 if (!li.getClassName().equals(lockInfo.getClassName())) { 255 throw new RuntimeException("Class Name = " + 256 li.getClassName() + " expected = " + lockInfo.getClassName()); 257 } 258 if (li.getIdentityHashCode() != lockInfo.getIdentityHashCode()) { 259 throw new RuntimeException("Class Name = " + 260 li.getIdentityHashCode() + " expected = " + 261 lockInfo.getIdentityHashCode()); 262 } 263 } 264 265 public static void badNameCompositeData() throws Exception { 266 CompositeData cd = Factory.makeCompositeDataWithBadNames(); 267 try { 268 ThreadInfo info = ThreadInfo.from(cd); 269 throw new RuntimeException("IllegalArgumentException not thrown"); 270 } catch (IllegalArgumentException e) { } 271 } 272 273 public static void badTypeCompositeData() throws Exception { 274 CompositeData cd = Factory.makeCompositeDataWithBadTypes(); 275 276 try { 277 ThreadInfo info = ThreadInfo.from(cd); 278 throw new RuntimeException("IllegalArgumentException not thrown"); 279 } catch (IllegalArgumentException e) { } 280 } 281 282 private static final int THREAD_ID = 0; 283 private static final int THREAD_NAME = 1; 284 private static final int THREAD_STATE = 2; 285 private static final int BLOCKED_TIME = 3; 286 private static final int BLOCKED_COUNT = 4; 287 private static final int WAITED_TIME = 5; 288 private static final int WAITED_COUNT = 6; 289 private static final int LOCK_NAME = 7; 290 private static final int LOCK_OWNER_ID = 8; 291 private static final int LOCK_OWNER_NAME = 9; 292 private static final int STACK_TRACE = 10; 293 private static final int SUSPENDED = 11; 294 private static final int IN_NATIVE = 12; 295 // JDK 6 ThreadInfo attributes 296 private static final int LOCK_INFO = 13; 297 private static final int LOCKED_MONITORS = 14; 298 private static final int LOCKED_SYNCS = 15; 299 // JDK 9 ThreadInfo attributes 300 private static final int DAEMON = 16; 301 private static final int PRIORITY = 17; 302 303 static class Factory { 304 305 static final CompositeType STE_COMPOSITE_TYPE; 306 static final CompositeType LOCK_INFO_COMPOSITE_TYPE; 307 static final CompositeType MONITOR_INFO_COMPOSITE_TYPE; 308 static final ArrayType STE_ARRAY_COMPOSITE_TYPE; 309 static final ArrayType LOCK_INFO_ARRAY_COMPOSITE_TYPE; 310 static final ArrayType MONITOR_INFO_ARRAY_COMPOSITE_TYPE; 311 312 static { 313 CompositeType steCType = null; 314 CompositeType lockInfoCType = null; 315 CompositeType monitorInfoCType = null; 316 ArrayType steArrayType = null; 317 ArrayType lockInfoArrayType = null; 318 ArrayType monitorInfoArrayType = null; 319 320 try { 321 steCType = (CompositeType) OpenTypeConverter.toOpenType(StackTraceElement.class); 322 lockInfoCType = (CompositeType) OpenTypeConverter.toOpenType(LockInfo.class); 323 monitorInfoCType = (CompositeType) OpenTypeConverter.toOpenType(MonitorInfo.class); 324 steArrayType = new ArrayType(1, steCType); 325 lockInfoArrayType = new ArrayType(1, lockInfoCType); 326 monitorInfoArrayType = new ArrayType(1, monitorInfoCType); 327 } catch (Exception e) { 328 throw new RuntimeException(e); 329 } 330 STE_COMPOSITE_TYPE = steCType; 331 LOCK_INFO_COMPOSITE_TYPE = lockInfoCType; 332 MONITOR_INFO_COMPOSITE_TYPE = monitorInfoCType; 333 STE_ARRAY_COMPOSITE_TYPE = steArrayType; 334 LOCK_INFO_ARRAY_COMPOSITE_TYPE = lockInfoArrayType; 335 MONITOR_INFO_ARRAY_COMPOSITE_TYPE = monitorInfoArrayType; 336 } 337 338 static CompositeData makeThreadInfoCompositeData() throws OpenDataException { 339 CompositeType ct = new CompositeType("MyCompositeType", 340 "CompositeType for ThreadInfo", 341 ITEM_NAMES, 342 ITEM_NAMES, 343 ITEM_TYPES); 344 return new CompositeDataSupport(ct, ITEM_NAMES, VALUES); 345 } 346 347 static CompositeData makeThreadInfoV5CompositeData() throws OpenDataException { 348 CompositeType ct = new CompositeType("MyCompositeType", 349 "CompositeType for JDK 5 ThreadInfo", 350 V5_ITEM_NAMES, 351 V5_ITEM_NAMES, 352 V5_ITEM_TYPES); 353 return new CompositeDataSupport(ct, V5_ITEM_NAMES, V5_VALUES); 354 } 355 356 static CompositeData makeCompositeDataWithBadTypes() throws OpenDataException { 357 OpenType[] badItemTypes = { 358 SimpleType.LONG, 359 SimpleType.STRING, 360 SimpleType.STRING, 361 SimpleType.LONG, 362 SimpleType.LONG, 363 SimpleType.LONG, 364 SimpleType.LONG, 365 SimpleType.STRING, 366 SimpleType.LONG, 367 SimpleType.STRING, 368 SimpleType.LONG, // bad type 369 SimpleType.BOOLEAN, 370 SimpleType.BOOLEAN, 371 SimpleType.LONG, // bad type 372 SimpleType.LONG, // bad type 373 SimpleType.LONG, // bad type 374 SimpleType.BOOLEAN, 375 SimpleType.INTEGER, 376 }; 377 378 CompositeType ct = 379 new CompositeType("Bad item types", 380 "CompositeType for ThreadInfo", 381 ITEM_NAMES, 382 ITEM_NAMES, 383 badItemTypes); 384 385 // Copy before mutating to avoid affecting other tests. 386 Object[] localValues = VALUES.clone(); 387 388 // patch values[STACK_TRACE] to Long 389 localValues[STACK_TRACE] = Long.valueOf(1000); 390 localValues[LOCK_INFO] = Long.valueOf(1000); 391 localValues[LOCKED_MONITORS] = Long.valueOf(1000); 392 localValues[LOCKED_SYNCS] = Long.valueOf(1000); 393 return new CompositeDataSupport(ct, ITEM_NAMES, localValues); 394 } 395 396 static CompositeData makeCompositeDataWithBadNames() throws OpenDataException { 397 String[] badItemNames = ITEM_NAMES.clone(); 398 badItemNames[STACK_TRACE] = "BadStackTrace"; // bad item name 399 400 CompositeType ct = new CompositeType("Bad item names", 401 "CompositeType for ThreadInfo", 402 badItemNames, 403 badItemNames, 404 ITEM_TYPES); 405 return new CompositeDataSupport(ct, 406 badItemNames, 407 VALUES); 408 } 409 410 /* 411 * Create a CompositeData of ThreadInfo without JDK 6 attributes 412 */ 413 static CompositeData makeCompositeDataMissingV6() throws OpenDataException { 414 String[] itemNames = concat(V5_ITEM_NAMES, V9_ITEM_NAMES).toArray(String[]::new); 415 OpenType[] itemTypes = concat(V5_ITEM_TYPES, V9_ITEM_TYPES).toArray(OpenType[]::new); 416 Object[] values = concat(V5_VALUES, V9_VALUES).toArray(Object[]::new); 417 418 CompositeType ct = 419 new CompositeType("InvalidCompositeType", 420 "CompositeType for ThreadInfo", 421 itemNames, 422 itemNames, 423 itemTypes); 424 return new CompositeDataSupport(ct, itemNames, values); 425 } 426 427 static CompositeData makeStackTraceElement() { 428 Object[] steValue = { 429 STE.getClassLoaderName(), 430 STE.getModuleName(), 431 STE.getModuleVersion(), 432 STE.getClassName(), 433 STE.getMethodName(), 434 STE.getFileName(), 435 Integer.valueOf(STE.getLineNumber()), 436 Boolean.valueOf(STE.isNativeMethod()), 437 }; 438 439 try { 440 return new CompositeDataSupport(STE_COMPOSITE_TYPE, 441 STE_ITEM_NAMES, 442 steValue); 443 } catch (OpenDataException e) { 444 throw new RuntimeException(e); 445 } 446 } 447 448 static CompositeData makeStackTraceElementV5() throws OpenDataException { 449 CompositeType steV5CType = 450 new CompositeType("JDK 5 StackTraceElement", 451 "CompositeType for JDK 5 StackTraceElement", 452 STE_V5_ITEM_NAMES, 453 STE_V5_ITEM_NAMES, 454 STE_V5_ITEM_TYPES); 455 456 Object[] steV5Value = { 457 STE.getClassName(), 458 STE.getMethodName(), 459 STE.getFileName(), 460 Integer.valueOf(STE.getLineNumber()), 461 Boolean.valueOf(STE.isNativeMethod()), 462 }; 463 464 return new CompositeDataSupport(steV5CType, STE_V5_ITEM_NAMES, steV5Value); 465 } 466 467 /* 468 * Create a CompositeData of ThreadInfo without JDK 5 StackTraceElement 469 */ 470 static CompositeData makeThreadInfoWithV5StackTrace() throws OpenDataException { 471 OpenType[] badTypes = ITEM_TYPES.clone(); 472 Object[] badValues = VALUES.clone(); 473 474 CompositeData[] stackTrace = new CompositeData[1]; 475 stackTrace[0] = makeStackTraceElementV5(); 476 badTypes[STACK_TRACE] = new ArrayType(1, stackTrace[0].getCompositeType()); 477 badValues[STACK_TRACE] = stackTrace; 478 CompositeType ct = new CompositeType("CompositeType", 479 "ThreadInfo with JDK 5 StackTraceElement", 480 ITEM_NAMES, 481 ITEM_NAMES, 482 badTypes); 483 return new CompositeDataSupport(ct, ITEM_NAMES, badValues); 484 } 485 486 /* 487 * Create MonitorInfo with JDK 5 StackTraceElement (i.e. JDK 6 MonitorInfo) 488 * The value of "lockedStackFrame" attribute is null to ensure that 489 * the validation is done. 490 */ 491 static CompositeData makeV6MonitorInfo() throws OpenDataException { 492 CompositeData steV5 = makeStackTraceElementV5(); 493 494 String[] names = MONITOR_INFO_COMPOSITE_TYPE.keySet().toArray(new String[0]); 495 OpenType[] types = new OpenType[names.length]; 496 for (int i=0; i < names.length; i++) { 497 String n = names[i]; 498 types[i] = "lockedStackFrame".equals(n) 499 ? steV5.getCompositeType() 500 : MONITOR_INFO_COMPOSITE_TYPE.getType(n); 501 } 502 503 CompositeType ctype = 504 new CompositeType("JDK 6 MonitorInfo", 505 "CompositeType for JDK 6 MonitorInfo", 506 names, 507 names, 508 types); 509 510 Object[] values = { 511 lockClassName, 512 lockIdentityHashCode, 513 -1, 514 null 515 }; 516 517 return new CompositeDataSupport(ctype, names, values); 518 } 519 520 /* 521 * Create a CompositeData of ThreadInfo with incompatible MonitorInfo 522 */ 523 static CompositeData makeThreadInfoWithIncompatibleMonitorInfo() throws OpenDataException { 524 OpenType[] badTypes = ITEM_TYPES.clone(); 525 Object[] badValues = VALUES.clone(); 526 527 CompositeData[] lockedMonitors = new CompositeData[1]; 528 lockedMonitors[0] = makeV6MonitorInfo(); 529 badTypes[LOCKED_MONITORS] = new ArrayType(1, lockedMonitors[0].getCompositeType()); 530 badValues[LOCKED_MONITORS] = lockedMonitors; 531 CompositeType ct = new CompositeType("CompositeType", 532 "ThreadInfo with incompatible MonitorInfo", 533 ITEM_NAMES, 534 ITEM_NAMES, 535 badTypes); 536 return new CompositeDataSupport(ct, ITEM_NAMES, badValues); 537 } 538 539 static CompositeData makeNewMonitorInfo() throws OpenDataException { 540 String[] names = Stream.concat(MONITOR_INFO_COMPOSITE_TYPE.keySet().stream(), 541 Stream.of("extra")).toArray(String[]::new); 542 OpenType[] types = new OpenType[names.length]; 543 for (int i=0; i < names.length; i++) { 544 String n = names[i]; 545 types[i] = "extra".equals(n) 546 ? SimpleType.STRING 547 : MONITOR_INFO_COMPOSITE_TYPE.getType(n); 548 } 549 550 CompositeType compositeType = 551 new CompositeType("JDK X MonitorInfo", 552 "CompositeType for JDK X MonitorInfo", 553 names, 554 names, 555 types); 556 557 Object[] values = { 558 lockClassName, 559 lockIdentityHashCode, 560 Integer.valueOf(1), 561 makeStackTraceElement(), 562 "extra" 563 }; 564 565 return new CompositeDataSupport(compositeType, names, values); 566 } 567 568 /* 569 * Create a CompositeData of ThreadInfo with a newer version of MonitorInfo 570 */ 571 static CompositeData makeThreadInfoWithNewMonitorInfo() throws OpenDataException { 572 OpenType[] types = ITEM_TYPES.clone(); 573 Object[] badValues = VALUES.clone(); 574 575 CompositeData[] lockedMonitors = new CompositeData[1]; 576 lockedMonitors[0] = makeNewMonitorInfo(); 577 types[LOCKED_MONITORS] = new ArrayType(1, lockedMonitors[0].getCompositeType()); 578 badValues[LOCKED_MONITORS] = lockedMonitors; 579 CompositeType ct = new CompositeType("CompositeType", 580 "ThreadInfo with JDK 5 MonitorInfo", 581 ITEM_NAMES, 582 ITEM_NAMES, 583 types); 584 return new CompositeDataSupport(ct, ITEM_NAMES, badValues); 585 } 586 587 static CompositeData makeLockInfo() { 588 Object[] lockInfoValue = { 589 lockInfo.getClassName(), 590 lockInfo.getIdentityHashCode(), 591 }; 592 593 try { 594 return new CompositeDataSupport(LOCK_INFO_COMPOSITE_TYPE, 595 LOCK_INFO_ITEM_NAMES, 596 lockInfoValue); 597 } catch (OpenDataException e) { 598 throw new RuntimeException(e); 599 } 600 } 601 602 static CompositeData[] makeLockedSynchronizers() { 603 CompositeData[] lockedSyncs = new CompositeData[1]; 604 lockedSyncs[0] = makeLockInfo(); 605 return lockedSyncs; 606 } 607 608 static CompositeData[] makeLockedMonitors() { 609 CompositeData[] lockedMonitorsCD = new CompositeData[1]; 610 611 Object[] lockedMonitorsValue = { 612 lockInfo.getClassName(), 613 lockInfo.getIdentityHashCode(), 614 makeStackTraceElement(), 615 Integer.valueOf(1), 616 }; 617 try { 618 lockedMonitorsCD[0] = 619 new CompositeDataSupport(MONITOR_INFO_COMPOSITE_TYPE, 620 LOCKED_MONITORS_ITEM_NAMES, 621 lockedMonitorsValue); 622 } catch (OpenDataException e) { 623 throw new RuntimeException(e); 624 } 625 return lockedMonitorsCD; 626 } 627 628 static final String[] V5_ITEM_NAMES = { 629 "threadId", 630 "threadName", 631 "threadState", 632 "blockedTime", 633 "blockedCount", 634 "waitedTime", 635 "waitedCount", 636 "lockName", 637 "lockOwnerId", 638 "lockOwnerName", 639 "stackTrace", 640 "suspended", 641 "inNative", 642 }; 643 644 static final String[] V6_ITEM_NAMES = { 645 "lockInfo", 646 "lockedMonitors", 647 "lockedSynchronizers", 648 }; 649 650 static final String[] V9_ITEM_NAMES = { 651 "daemon", 652 "priority", 653 }; 654 655 static final OpenType[] V5_ITEM_TYPES = { 656 SimpleType.LONG, 657 SimpleType.STRING, 658 SimpleType.STRING, 659 SimpleType.LONG, 660 SimpleType.LONG, 661 SimpleType.LONG, 662 SimpleType.LONG, 663 SimpleType.STRING, 664 SimpleType.LONG, 665 SimpleType.STRING, 666 STE_ARRAY_COMPOSITE_TYPE, 667 SimpleType.BOOLEAN, 668 SimpleType.BOOLEAN, 669 }; 670 671 static final OpenType[] V6_ITEM_TYPES = { 672 LOCK_INFO_COMPOSITE_TYPE, 673 MONITOR_INFO_ARRAY_COMPOSITE_TYPE, 674 LOCK_INFO_ARRAY_COMPOSITE_TYPE, 675 }; 676 677 static final OpenType[] V9_ITEM_TYPES = { 678 SimpleType.BOOLEAN, 679 SimpleType.INTEGER, 680 }; 681 682 static final String[] STE_ITEM_NAMES = { 683 "classLoaderName", 684 "moduleName", 685 "moduleVersion", 686 "className", 687 "methodName", 688 "fileName", 689 "lineNumber", 690 "nativeMethod", 691 }; 692 693 static final String[] STE_V5_ITEM_NAMES = Arrays.copyOfRange(STE_ITEM_NAMES, 3, 8); 694 695 static final OpenType[] STE_V5_ITEM_TYPES = { 696 SimpleType.STRING, 697 SimpleType.STRING, 698 SimpleType.STRING, 699 SimpleType.INTEGER, 700 SimpleType.BOOLEAN 701 }; 702 703 static final String[] LOCK_INFO_ITEM_NAMES = { 704 "className", 705 "identityHashCode", 706 }; 707 708 static final String[] LOCKED_MONITORS_ITEM_NAMES = { 709 LOCK_INFO_ITEM_NAMES[0], 710 LOCK_INFO_ITEM_NAMES[1], 711 "lockedStackFrame", 712 "lockedStackDepth", 713 }; 714 715 static final Object[] V5_VALUES = { 716 Long.valueOf(100), 717 "FooThread", 718 "RUNNABLE", 719 Long.valueOf(200), 720 Long.valueOf(10), 721 Long.valueOf(300), 722 Long.valueOf(20), 723 lockName, 724 Long.valueOf(99), 725 "BarThread", 726 new CompositeData[] { makeStackTraceElement() }, 727 Boolean.valueOf(false), 728 Boolean.valueOf(false), 729 }; 730 731 static final Object[] V6_VALUES = { 732 makeLockInfo(), 733 makeLockedMonitors(), 734 makeLockedSynchronizers(), 735 }; 736 737 static final Object[] V9_VALUES = { 738 Boolean.valueOf(true), 739 Thread.NORM_PRIORITY, 740 }; 741 742 static final String[] ITEM_NAMES = 743 concat(V5_ITEM_NAMES, V6_ITEM_NAMES, V9_ITEM_NAMES).toArray(String[]::new); 744 745 static final OpenType[] ITEM_TYPES = 746 concat(V5_ITEM_TYPES, V6_ITEM_TYPES, V9_ITEM_TYPES).toArray(OpenType[]::new); 747 748 static final Object[] VALUES = 749 concat(V5_VALUES, V6_VALUES, V9_VALUES).toArray(Object[]::new); 750 751 static <T> Stream<T> concat(T[]... streams) { 752 return Stream.of(streams).flatMap(a -> Arrays.stream(a)); 753 } 754 } 755 }