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         if (ManagementFactoryHelper.isPlatformLoggingMXBeanAvailable()) {
 359             /**
 360              * Logging facility.
 361              */
 362             initMBeanList.add(new PlatformComponent<PlatformLoggingMXBean>() {
 363                 private final Set<String> platformLoggingMXBeanInterfaceNames
 364                     = Collections.unmodifiableSet(Collections.singleton(
 365                             "java.lang.management.PlatformLoggingMXBean"));
 366 
 367                 @Override
 368                 public Set<Class<? extends PlatformLoggingMXBean>> mbeanInterfaces() {
 369                     return Collections.singleton(PlatformLoggingMXBean.class);
 370                 }
 371 
 372                 @Override
 373                 public Set<String> mbeanInterfaceNames() {
 374                     return platformLoggingMXBeanInterfaceNames;
 375                 }
 376 
 377                 @Override
 378                 public String getObjectNamePattern() {
 379                     return "java.util.logging:type=Logging";
 380                 }
 381 
 382                 @Override
 383                 public Map<String, PlatformLoggingMXBean> nameToMBeanMap() {
 384                     return Collections.singletonMap(
 385                         "java.util.logging:type=Logging",
 386                         ManagementFactoryHelper.getPlatformLoggingMXBean());
 387                 }
 388             });
 389         }
 390 
 391         /**
 392          * Buffer pools.
 393          */
 394         initMBeanList.add(new PlatformComponent<BufferPoolMXBean>() {
 395             private final Set<String> bufferPoolMXBeanInterfaceNames
 396                     = Collections.unmodifiableSet(Collections.singleton(
 397                             "java.lang.management.BufferPoolMXBean"));
 398 
 399             @Override
 400             public Set<Class<? extends BufferPoolMXBean>> mbeanInterfaces() {
 401                 return Collections.singleton(BufferPoolMXBean.class);
 402             }
 403 
 404             @Override
 405             public Set<String> mbeanInterfaceNames() {
 406                 return bufferPoolMXBeanInterfaceNames;
 407             }
 408 
 409             @Override
 410             public String getObjectNamePattern() {
 411                 return "java.nio:type=BufferPool,name=*";
 412             }
 413 
 414             @Override
 415             public boolean isSingleton() {
 416                 return false; // zero or more instances
 417             }
 418 
 419             @Override
 420             public Map<String, BufferPoolMXBean> nameToMBeanMap() {
 421                 List<BufferPoolMXBean> list
 422                         = ManagementFactoryHelper.getBufferPoolMXBeans();
 423                 Map<String, BufferPoolMXBean> map;
 424                 if (list.isEmpty()) {
 425                     map = Collections.<String, BufferPoolMXBean>emptyMap();
 426                 } else {
 427                     map = new HashMap<>(list.size());
 428                     list.stream()
 429                         .forEach(mbean -> map.put(mbean.getObjectName().getCanonicalName(),mbean));
 430                 }
 431                 return map;
 432             }
 433         });
 434 
 435         /**
 436          * OperatingSystemMXBean
 437          */
 438         initMBeanList.add(new PlatformComponent<OperatingSystemMXBean>() {
 439             private final Set<String> operatingSystemMXBeanInterfaceNames
 440                     = Collections.unmodifiableSet(Collections.singleton(
 441                             "java.lang.management.OperatingSystemMXBean"));
 442 
 443             @Override
 444             public Set<Class<? extends OperatingSystemMXBean>> mbeanInterfaces() {
 445                 return Collections.singleton(OperatingSystemMXBean.class);
 446             }
 447 
 448             @Override
 449             public Set<String> mbeanInterfaceNames() {
 450                 return operatingSystemMXBeanInterfaceNames;
 451             }
 452 
 453             @Override
 454             public String getObjectNamePattern() {
 455                 return ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME;
 456             }
 457 
 458             @Override
 459             public Map<String, OperatingSystemMXBean> nameToMBeanMap() {
 460                 return Collections.singletonMap(
 461                         ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME,
 462                         ManagementFactoryHelper.getOperatingSystemMXBean());
 463             }
 464 
 465         });
 466 
 467         initMBeanList.trimToSize();
 468         return initMBeanList;
 469     }
 470 }