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