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