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 }