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.internal.access.SharedSecrets;
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 * VirtualThreadSchedulerMXBean.
165 */
166 if (!SharedSecrets.getJavaLangAccess().isCustomDefaultVirtualThreadScheduler()) {
167 initMBeanList.add(new PlatformComponent<VirtualThreadSchedulerMXBean>() {
168 private final Set<Class<? extends VirtualThreadSchedulerMXBean>> mbeanInterfaces =
169 Set.of(VirtualThreadSchedulerMXBean.class);
170 private final Set<String> mbeanInterfaceNames =
171 Set.of(VirtualThreadSchedulerMXBean.class.getName());
172 private VirtualThreadSchedulerMXBean impl;
173
174 @Override
175 public Set<Class<? extends VirtualThreadSchedulerMXBean>> mbeanInterfaces() {
176 return mbeanInterfaces;
177 }
178
179 @Override
180 public Set<String> mbeanInterfaceNames() {
181 return mbeanInterfaceNames;
182 }
183
184 @Override
185 public String getObjectNamePattern() {
186 return "jdk.management:type=VirtualThreadScheduler";
187 }
188
189 @Override
190 public Map<String, VirtualThreadSchedulerMXBean> nameToMBeanMap() {
191 VirtualThreadSchedulerMXBean impl = this.impl;
192 if (impl == null) {
193 this.impl = impl = VirtualThreadSchedulerImpls.create();
194 }
195 return Map.of("jdk.management:type=VirtualThreadScheduler", impl);
196 }
197 });
198 }
199
200 /**
201 * OperatingSystemMXBean
202 */
203 initMBeanList.add(new PlatformComponent<OperatingSystemMXBean>() {
204 private final Set<String> operatingSystemMXBeanInterfaceNames
205 = Collections.unmodifiableSet(
206 Stream.of("java.lang.management.OperatingSystemMXBean",
207 "com.sun.management.OperatingSystemMXBean",
208 "com.sun.management.UnixOperatingSystemMXBean")
209 .collect(Collectors.toSet()));
210
211 @Override
212 public Set<Class<? extends OperatingSystemMXBean>> mbeanInterfaces() {
213 return Stream.of(java.lang.management.OperatingSystemMXBean.class,
214 com.sun.management.OperatingSystemMXBean.class,
215 com.sun.management.UnixOperatingSystemMXBean.class)
216 .collect(Collectors.toSet());
217 }
218
219 @Override
220 public Set<String> mbeanInterfaceNames() {
221 return operatingSystemMXBeanInterfaceNames;
222 }
223
224 @Override
225 public String getObjectNamePattern() {
226 return ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME;
227 }
228
229 @Override
230 public Map<String, java.lang.management.OperatingSystemMXBean> nameToMBeanMap() {
231 return Collections.<String, java.lang.management.OperatingSystemMXBean>singletonMap(
232 ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME,
233 getOperatingSystemMXBean());
234 }
235 });
236
237 /**
238 * Diagnostic support for the HotSpot Virtual Machine.
239 */
240 initMBeanList.add(new PlatformComponent<com.sun.management.HotSpotDiagnosticMXBean>() {
241 private final Set<String> hotSpotDiagnosticMXBeanInterfaceNames =
242 Collections.singleton("com.sun.management.HotSpotDiagnosticMXBean");
243
244 @Override
245 public Set<Class<? extends com.sun.management.HotSpotDiagnosticMXBean>> mbeanInterfaces() {
246 return Collections.singleton(com.sun.management.HotSpotDiagnosticMXBean.class);
247 }
248
249 @Override
250 public Set<String> mbeanInterfaceNames() {
251 return hotSpotDiagnosticMXBeanInterfaceNames;
252 }
253
254 @Override
255 public String getObjectNamePattern() {
256 return "com.sun.management:type=HotSpotDiagnostic";
257 }
258
259 @Override
260 public Map<String, com.sun.management.HotSpotDiagnosticMXBean> nameToMBeanMap() {
261 return Collections.<String, com.sun.management.HotSpotDiagnosticMXBean>singletonMap(
262 "com.sun.management:type=HotSpotDiagnostic",
263 getDiagnosticMXBean());
264 }
265 });
266
267 /**
268 * Diagnostic command MBean
269 */
270 DiagnosticCommandMBean diagMBean = DiagnosticCommandImpl.getDiagnosticCommandMBean();
271 if (diagMBean != null) {
272 initMBeanList.add(new PlatformComponent<DynamicMBean>() {
273 final Set<String> dynamicMBeanInterfaceNames
274 = Collections.singleton("javax.management.DynamicMBean");
275
276 @Override
277 public Set<String> mbeanInterfaceNames() {
278 return dynamicMBeanInterfaceNames;
279 }
280
281 @Override
282 public Set<Class<? extends DynamicMBean>> mbeanInterfaces() {
283 // DynamicMBean cannot be used to find an MBean by ManagementFactory
284 return Collections.emptySet();
285 }
286
287 @Override
288 public String getObjectNamePattern() {
289 return DIAGNOSTIC_COMMAND_MBEAN_NAME;
290 }
291
292 @Override
293 public Map<String, DynamicMBean> nameToMBeanMap() {
294 return Collections.<String, DynamicMBean>singletonMap(
295 DIAGNOSTIC_COMMAND_MBEAN_NAME,
296 diagMBean);
297 }
298 });
299 }
300
301 initMBeanList.trimToSize();
302 return initMBeanList;
303 }
304
305 private static synchronized HotSpotDiagnosticMXBean getDiagnosticMXBean() {
306 if (hsDiagMBean == null) {
307 hsDiagMBean = new HotSpotDiagnostic();
308 }
309 return hsDiagMBean;
310 }
311
312 private static synchronized OperatingSystemMXBean getOperatingSystemMXBean() {
313 if (osMBean == null) {
314 osMBean = new OperatingSystemImpl(ManagementFactoryHelper.getVMManagement());
315 }
316 return osMBean;
317 }
318 }