1 /* 2 * Copyright (c) 2015, 2024, 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 package com.sun.management.internal; 26 27 import com.sun.management.DiagnosticCommandMBean; 28 import com.sun.management.HotSpotDiagnosticMXBean; 29 import com.sun.management.ThreadMXBean; 30 import java.lang.management.ManagementFactory; 31 import java.lang.management.MemoryManagerMXBean; 32 import java.lang.management.OperatingSystemMXBean; 33 import java.util.ArrayList; 34 import java.util.Collections; 35 import java.util.HashMap; 36 import java.util.List; 37 import java.util.Map; 38 import java.util.Set; 39 import java.util.stream.Collectors; 40 import java.util.stream.Stream; 41 import javax.management.DynamicMBean; 42 import jdk.management.AOTCacheMXBean; 43 import jdk.management.VirtualThreadSchedulerMXBean; 44 import sun.management.ManagementFactoryHelper; 45 import sun.management.spi.PlatformMBeanProvider; 46 47 @SuppressWarnings({"removal", "restricted"}) 48 public final class PlatformMBeanProviderImpl extends PlatformMBeanProvider { 49 static final String DIAGNOSTIC_COMMAND_MBEAN_NAME = 50 "com.sun.management:type=DiagnosticCommand"; 51 52 private final List<PlatformComponent<?>> mxbeanList; 53 private static HotSpotDiagnostic hsDiagMBean = null; 54 private static OperatingSystemMXBean osMBean = null; 55 56 static { 57 System.loadLibrary("management_ext"); 58 } 59 60 public PlatformMBeanProviderImpl() { 61 mxbeanList = Collections.unmodifiableList(init()); 62 } 63 64 @Override 65 public List<PlatformComponent<?>> getPlatformComponentList() { 66 return mxbeanList; 67 } 68 69 private List<PlatformComponent<?>> init() { 70 ArrayList<PlatformComponent<?>> initMBeanList = new ArrayList<>(); 71 /** 72 * Garbage Collector in the Java virtual machine. 73 */ 74 initMBeanList.add(new PlatformComponent<MemoryManagerMXBean>() { 75 private final Set<String> garbageCollectorMXBeanInterfaceNames 76 = Collections.unmodifiableSet( 77 Stream.of("java.lang.management.MemoryManagerMXBean", 78 "java.lang.management.GarbageCollectorMXBean", 79 "com.sun.management.GarbageCollectorMXBean") 80 .collect(Collectors.toSet())); 81 82 @Override 83 public Set<Class<? extends MemoryManagerMXBean>> mbeanInterfaces() { 84 return Stream.of(MemoryManagerMXBean.class, 85 java.lang.management.GarbageCollectorMXBean.class, 86 com.sun.management.GarbageCollectorMXBean.class) 87 .collect(Collectors.toSet()); 88 } 89 90 @Override 91 public Set<String> mbeanInterfaceNames() { 92 return garbageCollectorMXBeanInterfaceNames; 93 } 94 95 @Override 96 public String getObjectNamePattern() { 97 return ManagementFactory.GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE + ",name=*"; 98 } 99 100 @Override 101 public boolean isSingleton() { 102 return false; // zero or more instances 103 } 104 105 @Override 106 public Map<String, MemoryManagerMXBean> nameToMBeanMap() { 107 List<java.lang.management.GarbageCollectorMXBean> list 108 = ManagementFactoryHelper.getGarbageCollectorMXBeans(); 109 Map<String, MemoryManagerMXBean> map; 110 if (list.isEmpty()) { 111 map = Collections.emptyMap(); 112 } else { 113 map = new HashMap<>(list.size()); 114 for (MemoryManagerMXBean gcm : list) { 115 map.put(gcm.getObjectName().getCanonicalName(), 116 gcm); 117 } 118 } 119 120 return map; 121 } 122 }); 123 124 /** 125 * Threading system of the Java virtual machine. 126 */ 127 initMBeanList.add(new PlatformComponent<java.lang.management.ThreadMXBean>() { 128 private final Set<String> threadMXBeanInterfaceNames 129 = Collections.unmodifiableSet( 130 Stream.of("java.lang.management.ThreadMXBean", 131 "com.sun.management.ThreadMXBean") 132 .collect(Collectors.toSet())); 133 private ThreadMXBean threadMBean = null; 134 135 @Override 136 public Set<Class<? extends java.lang.management.ThreadMXBean>> mbeanInterfaces() { 137 return Stream.of(java.lang.management.ThreadMXBean.class, 138 com.sun.management.ThreadMXBean.class) 139 .collect(Collectors.toSet()); 140 } 141 142 @Override 143 public Set<String> mbeanInterfaceNames() { 144 return threadMXBeanInterfaceNames; 145 } 146 147 @Override 148 public String getObjectNamePattern() { 149 return ManagementFactory.THREAD_MXBEAN_NAME; 150 } 151 152 @Override 153 public synchronized Map<String, java.lang.management.ThreadMXBean> nameToMBeanMap() { 154 if (threadMBean == null) { 155 threadMBean = new HotSpotThreadImpl(ManagementFactoryHelper.getVMManagement()); 156 } 157 return Collections.singletonMap( 158 ManagementFactory.THREAD_MXBEAN_NAME, 159 threadMBean); 160 } 161 }); 162 163 /** 164 * AOTCacheMXBean. 165 */ 166 initMBeanList.add(new PlatformComponent<AOTCacheMXBean>() { 167 private final Set<Class<? extends AOTCacheMXBean>> mbeanInterfaces = 168 Set.of(AOTCacheMXBean.class); 169 private final Set<String> mbeanInterfaceNames = 170 Set.of(AOTCacheMXBean.class.getName()); 171 private AOTCacheMXBean impl; 172 173 @Override 174 public Set<Class<? extends AOTCacheMXBean>> mbeanInterfaces() { 175 return mbeanInterfaces; 176 } 177 178 @Override 179 public Set<String> mbeanInterfaceNames() { 180 return mbeanInterfaceNames; 181 } 182 183 @Override 184 public String getObjectNamePattern() { 185 return "jdk.management:type=AOTCache"; 186 } 187 188 @Override 189 public Map<String, AOTCacheMXBean> nameToMBeanMap() { 190 AOTCacheMXBean impl = this.impl; 191 if (impl == null) { 192 this.impl = impl = new AOTCacheImpl(ManagementFactoryHelper.getVMManagement()); 193 } 194 return Map.of("jdk.management:type=AOTCache", impl); 195 } 196 }); 197 198 /** 199 * VirtualThreadSchedulerMXBean. 200 */ 201 initMBeanList.add(new PlatformComponent<VirtualThreadSchedulerMXBean>() { 202 private final Set<Class<? extends VirtualThreadSchedulerMXBean>> mbeanInterfaces = 203 Set.of(VirtualThreadSchedulerMXBean.class); 204 private final Set<String> mbeanInterfaceNames = 205 Set.of(VirtualThreadSchedulerMXBean.class.getName()); 206 private VirtualThreadSchedulerMXBean impl; 207 208 @Override 209 public Set<Class<? extends VirtualThreadSchedulerMXBean>> mbeanInterfaces() { 210 return mbeanInterfaces; 211 } 212 213 @Override 214 public Set<String> mbeanInterfaceNames() { 215 return mbeanInterfaceNames; 216 } 217 218 @Override 219 public String getObjectNamePattern() { 220 return "jdk.management:type=VirtualThreadScheduler"; 221 } 222 223 @Override 224 public Map<String, VirtualThreadSchedulerMXBean> nameToMBeanMap() { 225 VirtualThreadSchedulerMXBean impl = this.impl; 226 if (impl == null) { 227 this.impl = impl = VirtualThreadSchedulerImpls.create(); 228 } 229 return Map.of("jdk.management:type=VirtualThreadScheduler", impl); 230 } 231 }); 232 233 /** 234 * OperatingSystemMXBean 235 */ 236 initMBeanList.add(new PlatformComponent<OperatingSystemMXBean>() { 237 private final Set<String> operatingSystemMXBeanInterfaceNames 238 = Collections.unmodifiableSet( 239 Stream.of("java.lang.management.OperatingSystemMXBean", 240 "com.sun.management.OperatingSystemMXBean", 241 "com.sun.management.UnixOperatingSystemMXBean") 242 .collect(Collectors.toSet())); 243 244 @Override 245 public Set<Class<? extends OperatingSystemMXBean>> mbeanInterfaces() { 246 return Stream.of(java.lang.management.OperatingSystemMXBean.class, 247 com.sun.management.OperatingSystemMXBean.class, 248 com.sun.management.UnixOperatingSystemMXBean.class) 249 .collect(Collectors.toSet()); 250 } 251 252 @Override 253 public Set<String> mbeanInterfaceNames() { 254 return operatingSystemMXBeanInterfaceNames; 255 } 256 257 @Override 258 public String getObjectNamePattern() { 259 return ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME; 260 } 261 262 @Override 263 public Map<String, java.lang.management.OperatingSystemMXBean> nameToMBeanMap() { 264 return Collections.<String, java.lang.management.OperatingSystemMXBean>singletonMap( 265 ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME, 266 getOperatingSystemMXBean()); 267 } 268 }); 269 270 /** 271 * Diagnostic support for the HotSpot Virtual Machine. 272 */ 273 initMBeanList.add(new PlatformComponent<com.sun.management.HotSpotDiagnosticMXBean>() { 274 private final Set<String> hotSpotDiagnosticMXBeanInterfaceNames = 275 Collections.singleton("com.sun.management.HotSpotDiagnosticMXBean"); 276 277 @Override 278 public Set<Class<? extends com.sun.management.HotSpotDiagnosticMXBean>> mbeanInterfaces() { 279 return Collections.singleton(com.sun.management.HotSpotDiagnosticMXBean.class); 280 } 281 282 @Override 283 public Set<String> mbeanInterfaceNames() { 284 return hotSpotDiagnosticMXBeanInterfaceNames; 285 } 286 287 @Override 288 public String getObjectNamePattern() { 289 return "com.sun.management:type=HotSpotDiagnostic"; 290 } 291 292 @Override 293 public Map<String, com.sun.management.HotSpotDiagnosticMXBean> nameToMBeanMap() { 294 return Collections.<String, com.sun.management.HotSpotDiagnosticMXBean>singletonMap( 295 "com.sun.management:type=HotSpotDiagnostic", 296 getDiagnosticMXBean()); 297 } 298 }); 299 300 /** 301 * Diagnostic command MBean 302 */ 303 DiagnosticCommandMBean diagMBean = DiagnosticCommandImpl.getDiagnosticCommandMBean(); 304 if (diagMBean != null) { 305 initMBeanList.add(new PlatformComponent<DynamicMBean>() { 306 final Set<String> dynamicMBeanInterfaceNames 307 = Collections.singleton("javax.management.DynamicMBean"); 308 309 @Override 310 public Set<String> mbeanInterfaceNames() { 311 return dynamicMBeanInterfaceNames; 312 } 313 314 @Override 315 public Set<Class<? extends DynamicMBean>> mbeanInterfaces() { 316 // DynamicMBean cannot be used to find an MBean by ManagementFactory 317 return Collections.emptySet(); 318 } 319 320 @Override 321 public String getObjectNamePattern() { 322 return DIAGNOSTIC_COMMAND_MBEAN_NAME; 323 } 324 325 @Override 326 public Map<String, DynamicMBean> nameToMBeanMap() { 327 return Collections.<String, DynamicMBean>singletonMap( 328 DIAGNOSTIC_COMMAND_MBEAN_NAME, 329 diagMBean); 330 } 331 }); 332 } 333 334 initMBeanList.trimToSize(); 335 return initMBeanList; 336 } 337 338 private static synchronized HotSpotDiagnosticMXBean getDiagnosticMXBean() { 339 if (hsDiagMBean == null) { 340 hsDiagMBean = new HotSpotDiagnostic(); 341 } 342 return hsDiagMBean; 343 } 344 345 private static synchronized OperatingSystemMXBean getOperatingSystemMXBean() { 346 if (osMBean == null) { 347 osMBean = new OperatingSystemImpl(ManagementFactoryHelper.getVMManagement()); 348 } 349 return osMBean; 350 } 351 }