1 /*
2  * Copyright (c) 2015, 2020, 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 java.lang.management;
26 
27 import java.util.ArrayList;
28 import java.util.Collections;
29 import java.util.HashMap;
30 import java.util.List;
31 import java.util.Map;
32 import java.util.Set;
33 import java.util.function.Function;
34 import java.util.stream.Collectors;
35 import java.util.stream.Stream;
36 import javax.management.ObjectName;
37 import sun.management.ManagementFactoryHelper;
38 import sun.management.spi.PlatformMBeanProvider;
39 
40 class DefaultPlatformMBeanProvider extends PlatformMBeanProvider {
41     private final List<PlatformComponent<?>> mxbeanList;
42 
DefaultPlatformMBeanProvider()43     DefaultPlatformMBeanProvider() {
44         mxbeanList = Collections.unmodifiableList(init());
45     }
46 
47     @Override
getPlatformComponentList()48     public List<PlatformComponent<?>> getPlatformComponentList() {
49         return mxbeanList;
50     }
51 
init()52     private List<PlatformComponent<?>> init() {
53         ArrayList<PlatformComponent<?>> initMBeanList = new ArrayList<>();
54         /**
55          * Class loading system of the Java virtual machine.
56          */
57         initMBeanList.add(new PlatformComponent<ClassLoadingMXBean>() {
58             private final Set<String> classLoadingInterfaceNames =
59                     Collections.singleton("java.lang.management.ClassLoadingMXBean");
60 
61             @Override
62             public Set<Class<? extends ClassLoadingMXBean>> mbeanInterfaces() {
63                 return Collections.singleton(ClassLoadingMXBean.class);
64             }
65 
66             @Override
67             public Set<String> mbeanInterfaceNames() {
68                 return classLoadingInterfaceNames;
69             }
70 
71             @Override
72             public String getObjectNamePattern() {
73                 return ManagementFactory.CLASS_LOADING_MXBEAN_NAME;
74             }
75 
76             @Override
77             public Map<String, ClassLoadingMXBean> nameToMBeanMap() {
78                 return Collections.singletonMap(
79                         ManagementFactory.CLASS_LOADING_MXBEAN_NAME,
80                         ManagementFactoryHelper.getClassLoadingMXBean());
81             }
82         });
83 
84         /**
85          * Compilation system of the Java virtual machine.
86          */
87         initMBeanList.add(new PlatformComponent<CompilationMXBean>() {
88             private final Set<String> compilationMXBeanInterfaceNames
89                     = Collections.singleton("java.lang.management.CompilationMXBean");
90 
91             @Override
92             public Set<Class<? extends CompilationMXBean>> mbeanInterfaces() {
93                 return Collections.singleton(CompilationMXBean.class);
94             }
95 
96             @Override
97             public Set<String> mbeanInterfaceNames() {
98                 return compilationMXBeanInterfaceNames;
99             }
100 
101             @Override
102             public String getObjectNamePattern() {
103                 return ManagementFactory.COMPILATION_MXBEAN_NAME;
104             }
105 
106             @Override
107             public Map<String, CompilationMXBean> nameToMBeanMap() {
108                 CompilationMXBean m = ManagementFactoryHelper.getCompilationMXBean();
109                 if (m == null) {
110                     return Collections.emptyMap();
111                 } else {
112                     return Collections.singletonMap(
113                             ManagementFactory.COMPILATION_MXBEAN_NAME,
114                             ManagementFactoryHelper.getCompilationMXBean());
115                 }
116             }
117         });
118 
119         /**
120          * Memory system of the Java virtual machine.
121          */
122         initMBeanList.add(new PlatformComponent<MemoryMXBean>() {
123             private final Set<String> memoryMXBeanInterfaceNames
124                     = Collections.singleton("java.lang.management.MemoryMXBean");
125 
126             @Override
127             public Set<Class<? extends MemoryMXBean>> mbeanInterfaces() {
128                 return Collections.singleton(MemoryMXBean.class);
129             }
130 
131             @Override
132             public Set<String> mbeanInterfaceNames() {
133                 return memoryMXBeanInterfaceNames;
134             }
135 
136             @Override
137             public String getObjectNamePattern() {
138                 return ManagementFactory.MEMORY_MXBEAN_NAME;
139             }
140 
141             @Override
142             public Map<String, MemoryMXBean> nameToMBeanMap() {
143                 return Collections.singletonMap(
144                         ManagementFactory.MEMORY_MXBEAN_NAME,
145                         ManagementFactoryHelper.getMemoryMXBean());
146             }
147         });
148 
149         /**
150          * Garbage Collector in the Java virtual machine.
151          */
152         initMBeanList.add(new PlatformComponent<MemoryManagerMXBean>() {
153             private final Set<String> garbageCollectorMXBeanInterfaceNames
154                     = Collections.unmodifiableSet(
155                             Stream.of("java.lang.management.MemoryManagerMXBean",
156                                     "java.lang.management.GarbageCollectorMXBean")
157                             .collect(Collectors.toSet()));
158             @Override
159             public Set<Class<? extends MemoryManagerMXBean>> mbeanInterfaces() {
160                 return Stream.of(MemoryManagerMXBean.class,
161                         GarbageCollectorMXBean.class).collect(Collectors.toSet());
162             }
163 
164             @Override
165             public Set<String> mbeanInterfaceNames() {
166                 return garbageCollectorMXBeanInterfaceNames;
167             }
168 
169             @Override
170             public String getObjectNamePattern() {
171                 return ManagementFactory.GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE + ",name=*";
172             }
173 
174             @Override
175             public boolean isSingleton() {
176                 return false; // zero or more instances
177             }
178 
179             @Override
180             public Map<String, MemoryManagerMXBean> nameToMBeanMap() {
181                 List<GarbageCollectorMXBean> list
182                         = ManagementFactoryHelper.getGarbageCollectorMXBeans();
183                 Map<String, MemoryManagerMXBean> map;
184                 if (list.isEmpty()) {
185                     map = Collections.emptyMap();
186                 } else {
187                     map = new HashMap<>(list.size());
188                     for (MemoryManagerMXBean gcm : list) {
189                         map.put(gcm.getObjectName().getCanonicalName(),
190                                 gcm);
191                     }
192                 }
193                 return map;
194             }
195 
196         });
197 
198         /**
199          * Memory manager in the Java virtual machine.
200          */
201         initMBeanList.add(new PlatformComponent<MemoryManagerMXBean>() {
202             private final Set<String> memoryManagerMXBeanInterfaceNames
203                     = Collections.singleton("java.lang.management.MemoryManagerMXBean");
204 
205             @Override
206             public Set<Class<? extends MemoryManagerMXBean>> mbeanInterfaces() {
207                 return Collections.singleton(MemoryManagerMXBean.class);
208             }
209 
210             @Override
211             public Set<String> mbeanInterfaceNames() {
212                 return memoryManagerMXBeanInterfaceNames;
213             }
214 
215             @Override
216             public String getObjectNamePattern() {
217                 return ManagementFactory.MEMORY_MANAGER_MXBEAN_DOMAIN_TYPE + ",name=*";
218             }
219 
220             @Override
221             public boolean isSingleton() {
222                 return false; // zero or more instances
223             }
224 
225             @Override
226             public Map<String, MemoryManagerMXBean> nameToMBeanMap() {
227                 List<MemoryManagerMXBean> list
228                         = ManagementFactoryHelper.getMemoryManagerMXBeans();
229                 return list.stream()
230                         .filter(this::isMemoryManager)
231                         .collect(Collectors.toMap(
232                                 pmo -> pmo.getObjectName().getCanonicalName(), Function.identity()));
233             }
234 
235             // ManagementFactoryHelper.getMemoryManagerMXBeans() returns all
236             // memory managers - we need to filter out those that do not match
237             // the pattern for which we are registered
238             private boolean isMemoryManager(MemoryManagerMXBean mbean) {
239                 final ObjectName name = mbean.getObjectName();
240                 return ManagementFactory.MEMORY_MANAGER_MXBEAN_DOMAIN_TYPE.startsWith(name.getDomain())
241                         && ManagementFactory.MEMORY_MANAGER_MXBEAN_DOMAIN_TYPE.contains(
242                                 "type="+name.getKeyProperty("type"));
243             }
244         });
245 
246         /**
247          * Memory pool in the Java virtual machine.
248          */
249         initMBeanList.add(new PlatformComponent<MemoryPoolMXBean>() {
250             private final Set<String> memoryPoolMXBeanInterfaceNames
251                     = Collections.singleton("java.lang.management.MemoryPoolMXBean");
252 
253             @Override
254             public Set<Class<? extends MemoryPoolMXBean>> mbeanInterfaces() {
255                 return Collections.singleton(MemoryPoolMXBean.class);
256             }
257 
258             @Override
259             public Set<String> mbeanInterfaceNames() {
260                 return memoryPoolMXBeanInterfaceNames;
261             }
262 
263             @Override
264             public String getObjectNamePattern() {
265                 return ManagementFactory.MEMORY_POOL_MXBEAN_DOMAIN_TYPE + ",name=*";
266             }
267 
268             @Override
269             public boolean isSingleton() {
270                 return false; // zero or more instances
271             }
272 
273             @Override
274             public Map<String, MemoryPoolMXBean> nameToMBeanMap() {
275                 List<MemoryPoolMXBean> list
276                         = ManagementFactoryHelper.getMemoryPoolMXBeans();
277                 Map<String, MemoryPoolMXBean> map;
278                 if (list.isEmpty()) {
279                     map = Collections.<String, MemoryPoolMXBean>emptyMap();
280                 } else {
281                     map = new HashMap<>(list.size());
282                     for (MemoryPoolMXBean mpm : list) {
283                         map.put(mpm.getObjectName().getCanonicalName(),
284                                 mpm);
285                     }
286                 }
287                 return map;
288             }
289         });
290 
291         /**
292          * Runtime system of the Java virtual machine.
293          */
294         initMBeanList.add(new PlatformComponent<RuntimeMXBean>() {
295             private final Set<String> runtimeMXBeanInterfaceNames
296                     = Collections.singleton("java.lang.management.RuntimeMXBean");
297 
298             @Override
299             public Set<Class<? extends RuntimeMXBean>> mbeanInterfaces() {
300                 return Collections.singleton(RuntimeMXBean.class);
301             }
302 
303             @Override
304             public Set<String> mbeanInterfaceNames() {
305                 return runtimeMXBeanInterfaceNames;
306             }
307 
308             @Override
309             public String getObjectNamePattern() {
310                 return ManagementFactory.RUNTIME_MXBEAN_NAME;
311             }
312 
313             @Override
314             public Map<String, RuntimeMXBean> nameToMBeanMap() {
315                 return Collections.singletonMap(
316                         ManagementFactory.RUNTIME_MXBEAN_NAME,
317                         ManagementFactoryHelper.getRuntimeMXBean());
318             }
319         });
320 
321         /**
322          * Threading system of the Java virtual machine.
323          */
324         initMBeanList.add(new PlatformComponent<ThreadMXBean>() {
325             private final Set<String> threadMXBeanInterfaceNames
326                     = Collections.singleton("java.lang.management.ThreadMXBean");
327 
328             @Override
329             public Set<Class<? extends ThreadMXBean>> mbeanInterfaces() {
330                 return Collections.singleton(ThreadMXBean.class);
331             }
332 
333             @Override
334             public Set<String> mbeanInterfaceNames() {
335                 return threadMXBeanInterfaceNames;
336             }
337 
338             @Override
339             public String getObjectNamePattern() {
340                 return ManagementFactory.THREAD_MXBEAN_NAME;
341             }
342 
343             @Override
344             public Map<String, ThreadMXBean> nameToMBeanMap() {
345                 return Collections.singletonMap(
346                         ManagementFactory.THREAD_MXBEAN_NAME,
347                         ManagementFactoryHelper.getThreadMXBean());
348             }
349         });
350 
351         if (ManagementFactoryHelper.isPlatformLoggingMXBeanAvailable()) {
352             /**
353              * Logging facility.
354              */
355             initMBeanList.add(new PlatformComponent<PlatformLoggingMXBean>() {
356                 private final Set<String> platformLoggingMXBeanInterfaceNames
357                     = Collections.singleton("java.lang.management.PlatformLoggingMXBean");
358 
359                 @Override
360                 public Set<Class<? extends PlatformLoggingMXBean>> mbeanInterfaces() {
361                     return Collections.singleton(PlatformLoggingMXBean.class);
362                 }
363 
364                 @Override
365                 public Set<String> mbeanInterfaceNames() {
366                     return platformLoggingMXBeanInterfaceNames;
367                 }
368 
369                 @Override
370                 public String getObjectNamePattern() {
371                     return "java.util.logging:type=Logging";
372                 }
373 
374                 @Override
375                 public Map<String, PlatformLoggingMXBean> nameToMBeanMap() {
376                     return Collections.singletonMap(
377                         "java.util.logging:type=Logging",
378                         ManagementFactoryHelper.getPlatformLoggingMXBean());
379                 }
380             });
381         }
382 
383         /**
384          * Buffer pools.
385          */
386         initMBeanList.add(new PlatformComponent<BufferPoolMXBean>() {
387             private final Set<String> bufferPoolMXBeanInterfaceNames
388                     = Collections.singleton("java.lang.management.BufferPoolMXBean");
389 
390             @Override
391             public Set<Class<? extends BufferPoolMXBean>> mbeanInterfaces() {
392                 return Collections.singleton(BufferPoolMXBean.class);
393             }
394 
395             @Override
396             public Set<String> mbeanInterfaceNames() {
397                 return bufferPoolMXBeanInterfaceNames;
398             }
399 
400             @Override
401             public String getObjectNamePattern() {
402                 return "java.nio:type=BufferPool,name=*";
403             }
404 
405             @Override
406             public boolean isSingleton() {
407                 return false; // zero or more instances
408             }
409 
410             @Override
411             public Map<String, BufferPoolMXBean> nameToMBeanMap() {
412                 List<BufferPoolMXBean> list
413                         = ManagementFactoryHelper.getBufferPoolMXBeans();
414                 Map<String, BufferPoolMXBean> map;
415                 if (list.isEmpty()) {
416                     map = Collections.<String, BufferPoolMXBean>emptyMap();
417                 } else {
418                     map = new HashMap<>(list.size());
419                     list.stream()
420                         .forEach(mbean -> map.put(mbean.getObjectName().getCanonicalName(),mbean));
421                 }
422                 return map;
423             }
424         });
425 
426         /**
427          * OperatingSystemMXBean
428          */
429         initMBeanList.add(new PlatformComponent<OperatingSystemMXBean>() {
430             private final Set<String> operatingSystemMXBeanInterfaceNames
431                     = Collections.singleton("java.lang.management.OperatingSystemMXBean");
432 
433             @Override
434             public Set<Class<? extends OperatingSystemMXBean>> mbeanInterfaces() {
435                 return Collections.singleton(OperatingSystemMXBean.class);
436             }
437 
438             @Override
439             public Set<String> mbeanInterfaceNames() {
440                 return operatingSystemMXBeanInterfaceNames;
441             }
442 
443             @Override
444             public String getObjectNamePattern() {
445                 return ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME;
446             }
447 
448             @Override
449             public Map<String, OperatingSystemMXBean> nameToMBeanMap() {
450                 return Collections.singletonMap(
451                         ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME,
452                         ManagementFactoryHelper.getOperatingSystemMXBean());
453             }
454 
455         });
456 
457         initMBeanList.trimToSize();
458         return initMBeanList;
459     }
460 }
461