58 this.cdata = cd; 59 } 60 61 public ThreadInfo getThreadInfo() { 62 return threadInfo; 63 } 64 65 public static ThreadInfoCompositeData getInstance(CompositeData cd) { 66 validateCompositeData(cd); 67 return new ThreadInfoCompositeData(cd); 68 } 69 70 public static CompositeData toCompositeData(ThreadInfo ti) { 71 ThreadInfoCompositeData ticd = new ThreadInfoCompositeData(ti); 72 return ticd.getCompositeData(); 73 } 74 75 protected CompositeData getCompositeData() { 76 // Convert StackTraceElement[] to CompositeData[] 77 StackTraceElement[] stackTrace = threadInfo.getStackTrace(); 78 CompositeData[] stackTraceData = 79 new CompositeData[stackTrace.length]; 80 for (int i = 0; i < stackTrace.length; i++) { 81 StackTraceElement ste = stackTrace[i]; 82 stackTraceData[i] = StackTraceElementCompositeData.toCompositeData(ste); 83 } 84 85 // Convert MonitorInfo[] and LockInfo[] to CompositeData[] 86 CompositeData lockInfoData = 87 LockInfoCompositeData.toCompositeData(threadInfo.getLockInfo()); 88 89 // Convert LockInfo[] and MonitorInfo[] to CompositeData[] 90 LockInfo[] lockedSyncs = threadInfo.getLockedSynchronizers(); 91 CompositeData[] lockedSyncsData = 92 new CompositeData[lockedSyncs.length]; 93 for (int i = 0; i < lockedSyncs.length; i++) { 94 LockInfo li = lockedSyncs[i]; 95 lockedSyncsData[i] = LockInfoCompositeData.toCompositeData(li); 96 } 97 98 MonitorInfo[] lockedMonitors = threadInfo.getLockedMonitors(); 99 CompositeData[] lockedMonitorsData = 100 new CompositeData[lockedMonitors.length]; 101 for (int i = 0; i < lockedMonitors.length; i++) { 102 MonitorInfo mi = lockedMonitors[i]; 103 lockedMonitorsData[i] = MonitorInfoCompositeData.toCompositeData(mi); 104 } 105 106 // CONTENTS OF THIS ARRAY MUST BE SYNCHRONIZED WITH 107 // THREAD_INFO_ATTRIBUTES! 108 final Object[] threadInfoItemValues = { 109 threadInfo.getThreadId(), 110 threadInfo.getThreadName(), 111 threadInfo.getThreadState().name(), 112 threadInfo.getBlockedTime(), 113 threadInfo.getBlockedCount(), 114 threadInfo.getWaitedTime(), 115 threadInfo.getWaitedCount(), 116 lockInfoData, 117 threadInfo.getLockName(), 118 threadInfo.getLockOwnerId(), 119 threadInfo.getLockOwnerName(), 120 stackTraceData, 121 threadInfo.isSuspended(), 122 threadInfo.isInNative(), 123 lockedMonitorsData, 124 lockedSyncsData, 125 threadInfo.isDaemon(), 126 threadInfo.getPriority(), 127 }; 128 129 try { 130 return new CompositeDataSupport(compositeType(), 131 THREAD_INFO_ATTRIBTUES, 132 threadInfoItemValues); 133 } catch (OpenDataException e) { 134 // Should never reach here 135 throw new AssertionError(e); 136 } 137 } 138 139 // Attribute names 140 private static final String THREAD_ID = "threadId"; 141 private static final String THREAD_NAME = "threadName"; 142 private static final String THREAD_STATE = "threadState"; 143 private static final String BLOCKED_TIME = "blockedTime"; 144 private static final String BLOCKED_COUNT = "blockedCount"; 145 private static final String WAITED_TIME = "waitedTime"; 146 private static final String WAITED_COUNT = "waitedCount"; 147 private static final String LOCK_INFO = "lockInfo"; 148 private static final String LOCK_NAME = "lockName"; 149 private static final String LOCK_OWNER_ID = "lockOwnerId"; 150 private static final String LOCK_OWNER_NAME = "lockOwnerName"; 151 private static final String STACK_TRACE = "stackTrace"; 152 private static final String SUSPENDED = "suspended"; 166 WAITED_COUNT, 167 LOCK_NAME, 168 LOCK_OWNER_ID, 169 LOCK_OWNER_NAME, 170 STACK_TRACE, 171 SUSPENDED, 172 IN_NATIVE 173 }; 174 175 private static final String[] V6_ATTRIBUTES = { 176 LOCK_INFO, 177 LOCKED_MONITORS, 178 LOCKED_SYNCS, 179 }; 180 181 private static final String[] V9_ATTRIBUTES = { 182 DAEMON, 183 PRIORITY, 184 }; 185 186 private static final String[] THREAD_INFO_ATTRIBTUES = 187 Stream.of(V5_ATTRIBUTES, V6_ATTRIBUTES, V9_ATTRIBUTES) 188 .flatMap(Arrays::stream).toArray(String[]::new); 189 190 public long threadId() { 191 return getLong(cdata, THREAD_ID); 192 } 193 194 public String threadName() { 195 // The ThreadName item cannot be null so we check that 196 // it is present with a non-null value. 197 String name = getString(cdata, THREAD_NAME); 198 if (name == null) { 199 throw new IllegalArgumentException("Invalid composite data: " + 200 "Attribute " + THREAD_NAME + " has null value"); 201 } 202 return name; 203 } 204 205 public Thread.State threadState() { 206 return Thread.State.valueOf(getString(cdata, THREAD_STATE)); 207 } 208 209 public long blockedTime() { 348 if (cd == null) { 349 throw new NullPointerException("Null CompositeData"); 350 } 351 352 CompositeType type = cd.getCompositeType(); 353 int version; 354 if (Arrays.stream(V9_ATTRIBUTES).anyMatch(type::containsKey)) { 355 version = Runtime.version().feature(); 356 } else if (Arrays.stream(V6_ATTRIBUTES).anyMatch(type::containsKey)) { 357 version = 6; 358 } else { 359 version = 5; 360 } 361 362 if (!isTypeMatched(ThreadInfoCompositeTypes.ofVersion(version), type)) { 363 throw new IllegalArgumentException( 364 "Unexpected composite type for ThreadInfo of version " + version); 365 } 366 } 367 368 public static CompositeType compositeType() { 369 return ThreadInfoCompositeTypes.compositeTypes.get(0); 370 } 371 372 static class ThreadInfoCompositeTypes { 373 static final int CURRENT = Runtime.version().feature(); 374 static final Map<Integer, CompositeType> compositeTypes = initCompositeTypes(); 375 /* 376 * Returns CompositeType of the given runtime version 377 */ 378 static CompositeType ofVersion(int version) { 379 return compositeTypes.get(version); 380 } 381 382 static Map<Integer, CompositeType> initCompositeTypes() { 383 Map<Integer, CompositeType> types = new HashMap<>(); 384 CompositeType ctype = initCompositeType(); 385 types.put(CURRENT, ctype); 386 types.put(5, initV5CompositeType(ctype)); 387 types.put(6, initV6CompositeType(ctype)); 388 return types; 389 } 390 391 static CompositeType initCompositeType() { 392 try { 393 return (CompositeType)MappedMXBeanType.toOpenType(ThreadInfo.class); 394 } catch (OpenDataException e) { 395 // Should never reach here 396 throw new AssertionError(e); 397 } 398 } 399 400 static CompositeType initV5CompositeType(CompositeType threadInfoCompositeType) { 401 try { 402 OpenType<?>[] v5Types = new OpenType<?>[V5_ATTRIBUTES.length]; 403 for (int i = 0; i < v5Types.length; i++) { 404 String name = V5_ATTRIBUTES[i]; 405 v5Types[i] = name.equals(STACK_TRACE) | 58 this.cdata = cd; 59 } 60 61 public ThreadInfo getThreadInfo() { 62 return threadInfo; 63 } 64 65 public static ThreadInfoCompositeData getInstance(CompositeData cd) { 66 validateCompositeData(cd); 67 return new ThreadInfoCompositeData(cd); 68 } 69 70 public static CompositeData toCompositeData(ThreadInfo ti) { 71 ThreadInfoCompositeData ticd = new ThreadInfoCompositeData(ti); 72 return ticd.getCompositeData(); 73 } 74 75 protected CompositeData getCompositeData() { 76 // Convert StackTraceElement[] to CompositeData[] 77 StackTraceElement[] stackTrace = threadInfo.getStackTrace(); 78 CompositeData[] stackTraceData = new CompositeData[stackTrace.length]; 79 for (int i = 0; i < stackTrace.length; i++) { 80 StackTraceElement ste = stackTrace[i]; 81 stackTraceData[i] = StackTraceElementCompositeData.toCompositeData(ste); 82 } 83 84 // Convert MonitorInfo[] and LockInfo[] to CompositeData[] 85 CompositeData lockInfoData = 86 LockInfoCompositeData.toCompositeData(threadInfo.getLockInfo()); 87 88 // Convert LockInfo[] and MonitorInfo[] to CompositeData[] 89 LockInfo[] lockedSyncs = threadInfo.getLockedSynchronizers(); 90 CompositeData[] lockedSyncsData = new CompositeData[lockedSyncs.length]; 91 for (int i = 0; i < lockedSyncs.length; i++) { 92 LockInfo li = lockedSyncs[i]; 93 lockedSyncsData[i] = LockInfoCompositeData.toCompositeData(li); 94 } 95 96 MonitorInfo[] lockedMonitors = threadInfo.getLockedMonitors(); 97 CompositeData[] lockedMonitorsData = new CompositeData[lockedMonitors.length]; 98 for (int i = 0; i < lockedMonitors.length; i++) { 99 MonitorInfo mi = lockedMonitors[i]; 100 lockedMonitorsData[i] = MonitorInfoCompositeData.toCompositeData(mi); 101 } 102 103 // values may be null; can't use Map.of 104 Map<String,Object> items = new HashMap<>(); 105 items.put(THREAD_ID, threadInfo.getThreadId()); 106 items.put(THREAD_NAME, threadInfo.getThreadName()); 107 items.put(THREAD_STATE, threadInfo.getThreadState().name()); 108 items.put(BLOCKED_TIME, threadInfo.getBlockedTime()); 109 items.put(BLOCKED_COUNT, threadInfo.getBlockedCount()); 110 items.put(WAITED_TIME, threadInfo.getWaitedTime()); 111 items.put(WAITED_COUNT, threadInfo.getWaitedCount()); 112 items.put(LOCK_INFO, lockInfoData); 113 items.put(LOCK_NAME, threadInfo.getLockName()); 114 items.put(LOCK_OWNER_ID, threadInfo.getLockOwnerId()); 115 items.put(LOCK_OWNER_NAME, threadInfo.getLockOwnerName()); 116 items.put(STACK_TRACE, stackTraceData); 117 items.put(SUSPENDED, threadInfo.isSuspended()); 118 items.put(IN_NATIVE, threadInfo.isInNative()); 119 items.put(LOCKED_MONITORS, lockedMonitorsData); 120 items.put(LOCKED_SYNCS, lockedSyncsData); 121 items.put(DAEMON, threadInfo.isDaemon()); 122 items.put(PRIORITY, threadInfo.getPriority()); 123 124 try { 125 return new CompositeDataSupport(ThreadInfoCompositeTypes.ofVersion(RUNTIME_VERSION), items); 126 } catch (OpenDataException e) { 127 // Should never reach here 128 throw new AssertionError(e); 129 } 130 } 131 132 // Attribute names 133 private static final String THREAD_ID = "threadId"; 134 private static final String THREAD_NAME = "threadName"; 135 private static final String THREAD_STATE = "threadState"; 136 private static final String BLOCKED_TIME = "blockedTime"; 137 private static final String BLOCKED_COUNT = "blockedCount"; 138 private static final String WAITED_TIME = "waitedTime"; 139 private static final String WAITED_COUNT = "waitedCount"; 140 private static final String LOCK_INFO = "lockInfo"; 141 private static final String LOCK_NAME = "lockName"; 142 private static final String LOCK_OWNER_ID = "lockOwnerId"; 143 private static final String LOCK_OWNER_NAME = "lockOwnerName"; 144 private static final String STACK_TRACE = "stackTrace"; 145 private static final String SUSPENDED = "suspended"; 159 WAITED_COUNT, 160 LOCK_NAME, 161 LOCK_OWNER_ID, 162 LOCK_OWNER_NAME, 163 STACK_TRACE, 164 SUSPENDED, 165 IN_NATIVE 166 }; 167 168 private static final String[] V6_ATTRIBUTES = { 169 LOCK_INFO, 170 LOCKED_MONITORS, 171 LOCKED_SYNCS, 172 }; 173 174 private static final String[] V9_ATTRIBUTES = { 175 DAEMON, 176 PRIORITY, 177 }; 178 179 public long threadId() { 180 return getLong(cdata, THREAD_ID); 181 } 182 183 public String threadName() { 184 // The ThreadName item cannot be null so we check that 185 // it is present with a non-null value. 186 String name = getString(cdata, THREAD_NAME); 187 if (name == null) { 188 throw new IllegalArgumentException("Invalid composite data: " + 189 "Attribute " + THREAD_NAME + " has null value"); 190 } 191 return name; 192 } 193 194 public Thread.State threadState() { 195 return Thread.State.valueOf(getString(cdata, THREAD_STATE)); 196 } 197 198 public long blockedTime() { 337 if (cd == null) { 338 throw new NullPointerException("Null CompositeData"); 339 } 340 341 CompositeType type = cd.getCompositeType(); 342 int version; 343 if (Arrays.stream(V9_ATTRIBUTES).anyMatch(type::containsKey)) { 344 version = Runtime.version().feature(); 345 } else if (Arrays.stream(V6_ATTRIBUTES).anyMatch(type::containsKey)) { 346 version = 6; 347 } else { 348 version = 5; 349 } 350 351 if (!isTypeMatched(ThreadInfoCompositeTypes.ofVersion(version), type)) { 352 throw new IllegalArgumentException( 353 "Unexpected composite type for ThreadInfo of version " + version); 354 } 355 } 356 357 static final int RUNTIME_VERSION = Runtime.version().feature(); 358 static class ThreadInfoCompositeTypes { 359 static final Map<Integer, CompositeType> compositeTypes = initCompositeTypes(); 360 /* 361 * Returns CompositeType of the given runtime version 362 */ 363 static CompositeType ofVersion(int version) { 364 return compositeTypes.get(version); 365 } 366 367 static Map<Integer, CompositeType> initCompositeTypes() { 368 Map<Integer, CompositeType> types = new HashMap<>(); 369 CompositeType ctype = initCompositeType(); 370 types.put(RUNTIME_VERSION, ctype); 371 types.put(5, initV5CompositeType(ctype)); 372 types.put(6, initV6CompositeType(ctype)); 373 return types; 374 } 375 376 static CompositeType initCompositeType() { 377 try { 378 return (CompositeType)MappedMXBeanType.toOpenType(ThreadInfo.class); 379 } catch (OpenDataException e) { 380 // Should never reach here 381 throw new AssertionError(e); 382 } 383 } 384 385 static CompositeType initV5CompositeType(CompositeType threadInfoCompositeType) { 386 try { 387 OpenType<?>[] v5Types = new OpenType<?>[V5_ATTRIBUTES.length]; 388 for (int i = 0; i < v5Types.length; i++) { 389 String name = V5_ATTRIBUTES[i]; 390 v5Types[i] = name.equals(STACK_TRACE) |