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