1 /* 2 * Copyright (c) 2003, 2008, 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 26 package java.lang.management; 27 import javax.management.DynamicMBean; 28 import javax.management.MBeanServer; 29 import javax.management.MBeanServerConnection; 30 import javax.management.MBeanServerFactory; 31 import javax.management.MBeanServerPermission; 32 import javax.management.NotificationEmitter; 33 import javax.management.ObjectInstance; 34 import javax.management.ObjectName; 35 import javax.management.InstanceAlreadyExistsException; 36 import javax.management.InstanceNotFoundException; 37 import javax.management.MalformedObjectNameException; 38 import javax.management.MBeanRegistrationException; 39 import javax.management.NotCompliantMBeanException; 40 import javax.management.StandardEmitterMBean; 41 import javax.management.StandardMBean; 42 import java.util.Collections; 43 import java.util.List; 44 import java.util.Set; 45 import java.util.TreeSet; 46 import java.security.AccessController; 47 import java.security.Permission; 48 import java.security.PrivilegedAction; 49 import java.security.PrivilegedActionException; 50 import java.security.PrivilegedExceptionAction; 51 import javax.management.JMX; 52 import sun.management.ManagementFactoryHelper; 53 54 /** 55 * The {@code ManagementFactory} class is a factory class for getting 56 * managed beans for the Java platform. 57 * This class consists of static methods each of which returns 58 * one or more <i>platform MXBeans</i> representing 59 * the management interface of a component of the Java virtual 60 * machine. 61 * <p> 62 * <h4><a name="MXBean">Platform MXBeans</a></h4> 63 * <p> 64 * A platform MXBean is a <i>managed bean</i> that 65 * conforms to the <a href="../../../javax/management/package-summary.html">JMX</a> 66 * Instrumentation Specification and only uses a set of basic data types. 67 * A JMX management application and the {@linkplain 68 * #getPlatformMBeanServer platform MBeanServer} 69 * can interoperate without requiring classes for MXBean specific 70 * data types. 71 * The data types being transmitted between the JMX connector 72 * server and the connector client are 73 * {@linkplain javax.management.openmbean.OpenType open types} 74 * and this allows interoperation across versions. 75 * See <a href="../../../javax/management/MXBean.html#MXBean-spec"> 76 * the specification of MXBeans</a> for details. 77 * 78 * <a name="MXBeanNames"></a> 79 * <p>Each platform MXBean is a {@link PlatformManagedObject} 80 * and it has a unique 81 * {@link javax.management.ObjectName ObjectName} for 82 * registration in the platform {@code MBeanServer} as returned by 83 * by the {@link PlatformManagedObject#getObjectName getObjectName} 84 * method. 85 * 86 * <p> 87 * An application can access a platform MXBean in the following ways: 88 * <h5>1. Direct access to an MXBean interface</h5> 89 * <blockquote> 90 * <ul> 91 * <li>Get an MXBean instance by calling the 92 * {@link #getPlatformMXBean(Class) getPlatformMXBean} or 93 * {@link #getPlatformMXBeans(Class) getPlatformMXBeans} method 94 * and access the MXBean locally in the running 95 * virtual machine. 96 * </li> 97 * <li>Construct an MXBean proxy instance that forwards the 98 * method calls to a given {@link MBeanServer MBeanServer} by calling 99 * the {@link #getPlatformMXBean(MBeanServerConnection, Class)} or 100 * {@link #getPlatformMXBeans(MBeanServerConnection, Class)} method. 101 * The {@link #newPlatformMXBeanProxy newPlatformMXBeanProxy} method 102 * can also be used to construct an MXBean proxy instance of 103 * a given {@code ObjectName}. 104 * A proxy is typically constructed to remotely access 105 * an MXBean of another running virtual machine. 106 * </li> 107 * </ul> 108 * <h5>2. Indirect access to an MXBean interface via MBeanServer</h5> 109 * <ul> 110 * <li>Go through the platform {@code MBeanServer} to access MXBeans 111 * locally or a specific <tt>MBeanServerConnection</tt> to access 112 * MXBeans remotely. 113 * The attributes and operations of an MXBean use only 114 * <em>JMX open types</em> which include basic data types, 115 * {@link javax.management.openmbean.CompositeData CompositeData}, 116 * and {@link javax.management.openmbean.TabularData TabularData} 117 * defined in 118 * {@link javax.management.openmbean.OpenType OpenType}. 119 * The mapping is specified in 120 * the {@linkplain javax.management.MXBean MXBean} specification 121 * for details. 122 * </li> 123 * </ul> 124 * </blockquote> 125 * 126 * <p> 127 * The {@link #getPlatformManagementInterfaces getPlatformManagementInterfaces} 128 * method returns all management interfaces supported in the Java virtual machine 129 * including the standard management interfaces listed in the tables 130 * below as well as the management interfaces extended by the JDK implementation. 131 * <p> 132 * A Java virtual machine has a single instance of the following management 133 * interfaces: 134 * 135 * <blockquote> 136 * <table border> 137 * <tr> 138 * <th>Management Interface</th> 139 * <th>ObjectName</th> 140 * </tr> 141 * <tr> 142 * <td> {@link ClassLoadingMXBean} </td> 143 * <td> {@link #CLASS_LOADING_MXBEAN_NAME 144 * java.lang:type=ClassLoading}</td> 145 * </tr> 146 * <tr> 147 * <td> {@link MemoryMXBean} </td> 148 * <td> {@link #MEMORY_MXBEAN_NAME 149 * java.lang:type=Memory}</td> 150 * </tr> 151 * <tr> 152 * <td> {@link ThreadMXBean} </td> 153 * <td> {@link #THREAD_MXBEAN_NAME 154 * java.lang:type=Threading}</td> 155 * </tr> 156 * <tr> 157 * <td> {@link RuntimeMXBean} </td> 158 * <td> {@link #RUNTIME_MXBEAN_NAME 159 * java.lang:type=Runtime}</td> 160 * </tr> 161 * <tr> 162 * <td> {@link OperatingSystemMXBean} </td> 163 * <td> {@link #OPERATING_SYSTEM_MXBEAN_NAME 164 * java.lang:type=OperatingSystem}</td> 165 * </tr> 166 * <tr> 167 * <td> {@link PlatformLoggingMXBean} </td> 168 * <td> {@link java.util.logging.LogManager#LOGGING_MXBEAN_NAME 169 * java.util.logging:type=Logging}</td> 170 * </tr> 171 * </table> 172 * </blockquote> 173 * 174 * <p> 175 * A Java virtual machine has zero or a single instance of 176 * the following management interfaces. 177 * 178 * <blockquote> 179 * <table border> 180 * <tr> 181 * <th>Management Interface</th> 182 * <th>ObjectName</th> 183 * </tr> 184 * <tr> 185 * <td> {@link CompilationMXBean} </td> 186 * <td> {@link #COMPILATION_MXBEAN_NAME 187 * java.lang:type=Compilation}</td> 188 * </tr> 189 * </table> 190 * </blockquote> 191 * 192 * <p> 193 * A Java virtual machine may have one or more instances of the following 194 * management interfaces. 195 * <blockquote> 196 * <table border> 197 * <tr> 198 * <th>Management Interface</th> 199 * <th>ObjectName</th> 200 * </tr> 201 * <tr> 202 * <td> {@link GarbageCollectorMXBean} </td> 203 * <td> {@link #GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE 204 * java.lang:type=GarbageCollector}<tt>,name=</tt><i>collector's name</i></td> 205 * </tr> 206 * <tr> 207 * <td> {@link MemoryManagerMXBean} </td> 208 * <td> {@link #MEMORY_MANAGER_MXBEAN_DOMAIN_TYPE 209 * java.lang:type=MemoryManager}<tt>,name=</tt><i>manager's name</i></td> 210 * </tr> 211 * <tr> 212 * <td> {@link MemoryPoolMXBean} </td> 213 * <td> {@link #MEMORY_POOL_MXBEAN_DOMAIN_TYPE 214 * java.lang:type=MemoryPool}<tt>,name=</tt><i>pool's name</i></td> 215 * </tr> 216 * <tr> 217 * <td> {@link BufferPoolMXBean} </td> 218 * <td> {@code java.nio:type=BufferPool,name=}<i>pool name</i></td> 219 * </tr> 220 * </table> 221 * </blockquote> 222 * 223 * @see <a href="../../../javax/management/package-summary.html"> 224 * JMX Specification</a> 225 * @see <a href="package-summary.html#examples"> 226 * Ways to Access Management Metrics</a> 227 * @see javax.management.MXBean 228 * 229 * @author Mandy Chung 230 * @since 1.5 231 */ 232 public class ManagementFactory { 233 // A class with only static fields and methods. 234 private ManagementFactory() {}; 235 236 /** 237 * String representation of the 238 * <tt>ObjectName</tt> for the {@link ClassLoadingMXBean}. 239 */ 240 public final static String CLASS_LOADING_MXBEAN_NAME = 241 "java.lang:type=ClassLoading"; 242 243 /** 244 * String representation of the 245 * <tt>ObjectName</tt> for the {@link CompilationMXBean}. 246 */ 247 public final static String COMPILATION_MXBEAN_NAME = 248 "java.lang:type=Compilation"; 249 250 /** 251 * String representation of the 252 * <tt>ObjectName</tt> for the {@link MemoryMXBean}. 253 */ 254 public final static String MEMORY_MXBEAN_NAME = 255 "java.lang:type=Memory"; 256 257 /** 258 * String representation of the 259 * <tt>ObjectName</tt> for the {@link OperatingSystemMXBean}. 260 */ 261 public final static String OPERATING_SYSTEM_MXBEAN_NAME = 262 "java.lang:type=OperatingSystem"; 263 264 /** 265 * String representation of the 266 * <tt>ObjectName</tt> for the {@link RuntimeMXBean}. 267 */ 268 public final static String RUNTIME_MXBEAN_NAME = 269 "java.lang:type=Runtime"; 270 271 /** 272 * String representation of the 273 * <tt>ObjectName</tt> for the {@link ThreadMXBean}. 274 */ 275 public final static String THREAD_MXBEAN_NAME = 276 "java.lang:type=Threading"; 277 278 /** 279 * The domain name and the type key property in 280 * the <tt>ObjectName</tt> for a {@link GarbageCollectorMXBean}. 281 * The unique <tt>ObjectName</tt> for a <tt>GarbageCollectorMXBean</tt> 282 * can be formed by appending this string with 283 * "<tt>,name=</tt><i>collector's name</i>". 284 */ 285 public final static String GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE = 286 "java.lang:type=GarbageCollector"; 287 288 /** 289 * The domain name and the type key property in 290 * the <tt>ObjectName</tt> for a {@link MemoryManagerMXBean}. 291 * The unique <tt>ObjectName</tt> for a <tt>MemoryManagerMXBean</tt> 292 * can be formed by appending this string with 293 * "<tt>,name=</tt><i>manager's name</i>". 294 */ 295 public final static String MEMORY_MANAGER_MXBEAN_DOMAIN_TYPE= 296 "java.lang:type=MemoryManager"; 297 298 /** 299 * The domain name and the type key property in 300 * the <tt>ObjectName</tt> for a {@link MemoryPoolMXBean}. 301 * The unique <tt>ObjectName</tt> for a <tt>MemoryPoolMXBean</tt> 302 * can be formed by appending this string with 303 * <tt>,name=</tt><i>pool's name</i>. 304 */ 305 public final static String MEMORY_POOL_MXBEAN_DOMAIN_TYPE= 306 "java.lang:type=MemoryPool"; 307 308 /** 309 * Returns the managed bean for the class loading system of 310 * the Java virtual machine. 311 * 312 * @return a {@link ClassLoadingMXBean} object for 313 * the Java virtual machine. 314 */ 315 public static ClassLoadingMXBean getClassLoadingMXBean() { 316 return ManagementFactoryHelper.getClassLoadingMXBean(); 317 } 318 319 /** 320 * Returns the managed bean for the memory system of 321 * the Java virtual machine. 322 * 323 * @return a {@link MemoryMXBean} object for the Java virtual machine. 324 */ 325 public static MemoryMXBean getMemoryMXBean() { 326 return ManagementFactoryHelper.getMemoryMXBean(); 327 } 328 329 /** 330 * Returns the managed bean for the thread system of 331 * the Java virtual machine. 332 * 333 * @return a {@link ThreadMXBean} object for the Java virtual machine. 334 */ 335 public static ThreadMXBean getThreadMXBean() { 336 return ManagementFactoryHelper.getThreadMXBean(); 337 } 338 339 /** 340 * Returns the managed bean for the runtime system of 341 * the Java virtual machine. 342 * 343 * @return a {@link RuntimeMXBean} object for the Java virtual machine. 344 345 */ 346 public static RuntimeMXBean getRuntimeMXBean() { 347 return ManagementFactoryHelper.getRuntimeMXBean(); 348 } 349 350 /** 351 * Returns the managed bean for the compilation system of 352 * the Java virtual machine. This method returns <tt>null</tt> 353 * if the Java virtual machine has no compilation system. 354 * 355 * @return a {@link CompilationMXBean} object for the Java virtual 356 * machine or <tt>null</tt> if the Java virtual machine has 357 * no compilation system. 358 */ 359 public static CompilationMXBean getCompilationMXBean() { 360 return ManagementFactoryHelper.getCompilationMXBean(); 361 } 362 363 /** 364 * Returns the managed bean for the operating system on which 365 * the Java virtual machine is running. 366 * 367 * @return an {@link OperatingSystemMXBean} object for 368 * the Java virtual machine. 369 */ 370 public static OperatingSystemMXBean getOperatingSystemMXBean() { 371 return ManagementFactoryHelper.getOperatingSystemMXBean(); 372 } 373 374 /** 375 * Returns a list of {@link MemoryPoolMXBean} objects in the 376 * Java virtual machine. 377 * The Java virtual machine can have one or more memory pools. 378 * It may add or remove memory pools during execution. 379 * 380 * @return a list of <tt>MemoryPoolMXBean</tt> objects. 381 * 382 */ 383 public static List<MemoryPoolMXBean> getMemoryPoolMXBeans() { 384 return ManagementFactoryHelper.getMemoryPoolMXBeans(); 385 } 386 387 /** 388 * Returns a list of {@link MemoryManagerMXBean} objects 389 * in the Java virtual machine. 390 * The Java virtual machine can have one or more memory managers. 391 * It may add or remove memory managers during execution. 392 * 393 * @return a list of <tt>MemoryManagerMXBean</tt> objects. 394 * 395 */ 396 public static List<MemoryManagerMXBean> getMemoryManagerMXBeans() { 397 return ManagementFactoryHelper.getMemoryManagerMXBeans(); 398 } 399 400 401 /** 402 * Returns a list of {@link GarbageCollectorMXBean} objects 403 * in the Java virtual machine. 404 * The Java virtual machine may have one or more 405 * <tt>GarbageCollectorMXBean</tt> objects. 406 * It may add or remove <tt>GarbageCollectorMXBean</tt> 407 * during execution. 408 * 409 * @return a list of <tt>GarbageCollectorMXBean</tt> objects. 410 * 411 */ 412 public static List<GarbageCollectorMXBean> getGarbageCollectorMXBeans() { 413 return ManagementFactoryHelper.getGarbageCollectorMXBeans(); 414 } 415 416 private static MBeanServer platformMBeanServer; 417 /** 418 * Returns the platform {@link javax.management.MBeanServer MBeanServer}. 419 * On the first call to this method, it first creates the platform 420 * {@code MBeanServer} by calling the 421 * {@link javax.management.MBeanServerFactory#createMBeanServer 422 * MBeanServerFactory.createMBeanServer} 423 * method and registers each platform MXBean in this platform 424 * {@code MBeanServer} with its 425 * {@link PlatformManagedObject#getObjectName ObjectName}. 426 * This method, in subsequent calls, will simply return the 427 * initially created platform {@code MBeanServer}. 428 * <p> 429 * MXBeans that get created and destroyed dynamically, for example, 430 * memory {@link MemoryPoolMXBean pools} and 431 * {@link MemoryManagerMXBean managers}, 432 * will automatically be registered and deregistered into the platform 433 * {@code MBeanServer}. 434 * <p> 435 * If the system property {@code javax.management.builder.initial} 436 * is set, the platform {@code MBeanServer} creation will be done 437 * by the specified {@link javax.management.MBeanServerBuilder}. 438 * <p> 439 * It is recommended that this platform MBeanServer also be used 440 * to register other application managed beans 441 * besides the platform MXBeans. 442 * This will allow all MBeans to be published through the same 443 * {@code MBeanServer} and hence allow for easier network publishing 444 * and discovery. 445 * Name conflicts with the platform MXBeans should be avoided. 446 * 447 * @return the platform {@code MBeanServer}; the platform 448 * MXBeans are registered into the platform {@code MBeanServer} 449 * at the first time this method is called. 450 * 451 * @exception SecurityException if there is a security manager 452 * and the caller does not have the permission required by 453 * {@link javax.management.MBeanServerFactory#createMBeanServer}. 454 * 455 * @see javax.management.MBeanServerFactory 456 * @see javax.management.MBeanServerFactory#createMBeanServer 457 */ 458 public static synchronized MBeanServer getPlatformMBeanServer() { 459 SecurityManager sm = System.getSecurityManager(); 460 if (sm != null) { 461 Permission perm = new MBeanServerPermission("createMBeanServer"); 462 sm.checkPermission(perm); 463 } 464 465 if (platformMBeanServer == null) { 466 platformMBeanServer = MBeanServerFactory.createMBeanServer(); 467 for (PlatformComponent pc : PlatformComponent.values()) { 468 List<? extends PlatformManagedObject> list = 469 pc.getMXBeans(pc.getMXBeanInterface()); 470 for (PlatformManagedObject o : list) { 471 // Each PlatformComponent represents one management 472 // interface. Some MXBean may extend another one. 473 // The MXBean instances for one platform component 474 // (returned by pc.getMXBeans()) might be also 475 // the MXBean instances for another platform component. 476 // e.g. com.sun.management.GarbageCollectorMXBean 477 // 478 // So need to check if an MXBean instance is registered 479 // before registering into the platform MBeanServer 480 if (!platformMBeanServer.isRegistered(o.getObjectName())) { 481 addMXBean(platformMBeanServer, o); 482 } 483 } 484 } 485 } 486 return platformMBeanServer; 487 } 488 489 /** 490 * Returns a proxy for a platform MXBean interface of a 491 * given <a href="#MXBeanNames">MXBean name</a> 492 * that forwards its method calls through the given 493 * <tt>MBeanServerConnection</tt>. 494 * 495 * <p>This method is equivalent to: 496 * <blockquote> 497 * {@link java.lang.reflect.Proxy#newProxyInstance 498 * Proxy.newProxyInstance}<tt>(mxbeanInterface.getClassLoader(), 499 * new Class[] { mxbeanInterface }, handler)</tt> 500 * </blockquote> 501 * 502 * where <tt>handler</tt> is an {@link java.lang.reflect.InvocationHandler 503 * InvocationHandler} to which method invocations to the MXBean interface 504 * are dispatched. This <tt>handler</tt> converts an input parameter 505 * from an MXBean data type to its mapped open type before forwarding 506 * to the <tt>MBeanServer</tt> and converts a return value from 507 * an MXBean method call through the <tt>MBeanServer</tt> 508 * from an open type to the corresponding return type declared in 509 * the MXBean interface. 510 * 511 * <p> 512 * If the MXBean is a notification emitter (i.e., 513 * it implements 514 * {@link javax.management.NotificationEmitter NotificationEmitter}), 515 * both the <tt>mxbeanInterface</tt> and <tt>NotificationEmitter</tt> 516 * will be implemented by this proxy. 517 * 518 * <p> 519 * <b>Notes:</b> 520 * <ol> 521 * <li>Using an MXBean proxy is a convenience remote access to 522 * a platform MXBean of a running virtual machine. All method 523 * calls to the MXBean proxy are forwarded to an 524 * <tt>MBeanServerConnection</tt> where 525 * {@link java.io.IOException IOException} may be thrown 526 * when the communication problem occurs with the connector server. 527 * An application remotely accesses the platform MXBeans using 528 * proxy should prepare to catch <tt>IOException</tt> as if 529 * accessing with the <tt>MBeanServerConnector</tt> interface.</li> 530 * 531 * <li>When a client application is designed to remotely access MXBeans 532 * for a running virtual machine whose version is different than 533 * the version on which the application is running, 534 * it should prepare to catch 535 * {@link java.io.InvalidObjectException InvalidObjectException} 536 * which is thrown when an MXBean proxy receives a name of an 537 * enum constant which is missing in the enum class loaded in 538 * the client application. </li> 539 * 540 * <li>{@link javax.management.MBeanServerInvocationHandler 541 * MBeanServerInvocationHandler} or its 542 * {@link javax.management.MBeanServerInvocationHandler#newProxyInstance 543 * newProxyInstance} method cannot be used to create 544 * a proxy for a platform MXBean. The proxy object created 545 * by <tt>MBeanServerInvocationHandler</tt> does not handle 546 * the properties of the platform MXBeans described in 547 * the <a href="#MXBean">class specification</a>. 548 *</li> 549 * </ol> 550 * 551 * @param connection the <tt>MBeanServerConnection</tt> to forward to. 552 * @param mxbeanName the name of a platform MXBean within 553 * <tt>connection</tt> to forward to. <tt>mxbeanName</tt> must be 554 * in the format of {@link ObjectName ObjectName}. 555 * @param mxbeanInterface the MXBean interface to be implemented 556 * by the proxy. 557 * 558 * @throws IllegalArgumentException if 559 * <ul> 560 * <li><tt>mxbeanName</tt> is not with a valid 561 * {@link ObjectName ObjectName} format, or</li> 562 * <li>the named MXBean in the <tt>connection</tt> is 563 * not a MXBean provided by the platform, or</li> 564 * <li>the named MXBean is not registered in the 565 * <tt>MBeanServerConnection</tt>, or</li> 566 * <li>the named MXBean is not an instance of the given 567 * <tt>mxbeanInterface</tt></li> 568 * </ul> 569 * 570 * @throws java.io.IOException if a communication problem 571 * occurred when accessing the <tt>MBeanServerConnection</tt>. 572 */ 573 public static <T> T 574 newPlatformMXBeanProxy(MBeanServerConnection connection, 575 String mxbeanName, 576 Class<T> mxbeanInterface) 577 throws java.io.IOException { 578 579 final Class interfaceClass = mxbeanInterface; 580 // Only allow MXBean interfaces from rt.jar loaded by the 581 // bootstrap class loader 582 final ClassLoader loader = 583 AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() { 584 public ClassLoader run() { 585 return interfaceClass.getClassLoader(); 586 } 587 }); 588 if (loader != null) { 589 throw new IllegalArgumentException(mxbeanName + 590 " is not a platform MXBean"); 591 } 592 593 try { 594 final ObjectName objName = new ObjectName(mxbeanName); 595 // skip the isInstanceOf check for LoggingMXBean 596 String intfName = interfaceClass.getName(); 597 if (!connection.isInstanceOf(objName, intfName)) { 598 throw new IllegalArgumentException(mxbeanName + 599 " is not an instance of " + interfaceClass); 600 } 601 602 final Class[] interfaces; 603 // check if the registered MBean is a notification emitter 604 boolean emitter = connection.isInstanceOf(objName, NOTIF_EMITTER); 605 606 // create an MXBean proxy 607 return JMX.newMXBeanProxy(connection, objName, mxbeanInterface, 608 emitter); 609 } catch (InstanceNotFoundException|MalformedObjectNameException e) { 610 throw new IllegalArgumentException(e); 611 } 612 } 613 614 /** 615 * Returns the platform MXBean implementing 616 * the given {@code mxbeanInterface} which is specified 617 * to have one single instance in the Java virtual machine. 618 * This method may return {@code null} if the management interface 619 * is not implemented in the Java virtual machine (for example, 620 * a Java virtual machine with no compilation system does not 621 * implement {@link CompilationMXBean}); 622 * otherwise, this method is equivalent to calling: 623 * <pre> 624 * {@link #getPlatformMXBeans(Class) 625 * getPlatformMXBeans(mxbeanInterface)}.get(0); 626 * </pre> 627 * 628 * @param mxbeanInterface a management interface for a platform 629 * MXBean with one single instance in the Java virtual machine 630 * if implemented. 631 * 632 * @return the platform MXBean that implements 633 * {@code mxbeanInterface}, or {@code null} if not exist. 634 * 635 * @throws IllegalArgumentException if {@code mxbeanInterface} 636 * is not a platform management interface or 637 * not a singleton platform MXBean. 638 * 639 * @since 1.7 640 */ 641 public static <T extends PlatformManagedObject> 642 T getPlatformMXBean(Class<T> mxbeanInterface) { 643 PlatformComponent pc = PlatformComponent.getPlatformComponent(mxbeanInterface); 644 if (pc == null) 645 throw new IllegalArgumentException(mxbeanInterface.getName() + 646 " is not a platform management interface"); 647 return pc.getSingletonMXBean(mxbeanInterface); 648 } 649 650 /** 651 * Returns the list of platform MXBeans implementing 652 * the given {@code mxbeanInterface} in the Java 653 * virtual machine. 654 * The returned list may contain zero, one, or more instances. 655 * The number of instances in the returned list is defined 656 * in the specification of the given management interface. 657 * The order is undefined and there is no guarantee that 658 * the list returned is in the same order as previous invocations. 659 * 660 * @param mxbeanInterface a management interface for a platform 661 * MXBean 662 * 663 * @return the list of platform MXBeans that implement 664 * {@code mxbeanInterface}. 665 * 666 * @throws IllegalArgumentException if {@code mxbeanInterface} 667 * is not a platform management interface. 668 * 669 * @since 1.7 670 */ 671 public static <T extends PlatformManagedObject> List<T> 672 getPlatformMXBeans(Class<T> mxbeanInterface) { 673 PlatformComponent pc = PlatformComponent.getPlatformComponent(mxbeanInterface); 674 if (pc == null) 675 throw new IllegalArgumentException(mxbeanInterface.getName() + 676 " is not a platform management interface"); 677 return Collections.unmodifiableList(pc.getMXBeans(mxbeanInterface)); 678 } 679 680 /** 681 * Returns the platform MXBean proxy for 682 * {@code mxbeanInterface} which is specified to have one single 683 * instance in a Java virtual machine and the proxy will 684 * forward the method calls through the given {@code MBeanServerConnection}. 685 * This method may return {@code null} if the management interface 686 * is not implemented in the Java virtual machine being monitored 687 * (for example, a Java virtual machine with no compilation system 688 * does not implement {@link CompilationMXBean}); 689 * otherwise, this method is equivalent to calling: 690 * <pre> 691 * {@link #getPlatformMXBeans(MBeanServerConnection, Class) 692 * getPlatformMXBeans(connection, mxbeanInterface)}.get(0); 693 * </pre> 694 * 695 * @param connection the {@code MBeanServerConnection} to forward to. 696 * @param mxbeanInterface a management interface for a platform 697 * MXBean with one single instance in the Java virtual machine 698 * being monitored, if implemented. 699 * 700 * @return the platform MXBean proxy for 701 * forwarding the method calls of the {@code mxbeanInterface} 702 * through the given {@code MBeanServerConnection}, 703 * or {@code null} if not exist. 704 * 705 * @throws IllegalArgumentException if {@code mxbeanInterface} 706 * is not a platform management interface or 707 * not a singleton platform MXBean. 708 * @throws java.io.IOException if a communication problem 709 * occurred when accessing the {@code MBeanServerConnection}. 710 * 711 * @see #newPlatformMXBeanProxy 712 * @since 1.7 713 */ 714 public static <T extends PlatformManagedObject> 715 T getPlatformMXBean(MBeanServerConnection connection, 716 Class<T> mxbeanInterface) 717 throws java.io.IOException 718 { 719 PlatformComponent pc = PlatformComponent.getPlatformComponent(mxbeanInterface); 720 if (pc == null) 721 throw new IllegalArgumentException(mxbeanInterface.getName() + 722 " is not a platform management interface"); 723 return pc.getSingletonMXBean(connection, mxbeanInterface); 724 } 725 726 /** 727 * Returns the list of the platform MXBean proxies for 728 * forwarding the method calls of the {@code mxbeanInterface} 729 * through the given {@code MBeanServerConnection}. 730 * The returned list may contain zero, one, or more instances. 731 * The number of instances in the returned list is defined 732 * in the specification of the given management interface. 733 * The order is undefined and there is no guarantee that 734 * the list returned is in the same order as previous invocations. 735 * 736 * @param connection the {@code MBeanServerConnection} to forward to. 737 * @param mxbeanInterface a management interface for a platform 738 * MXBean 739 * 740 * @return the list of platform MXBean proxies for 741 * forwarding the method calls of the {@code mxbeanInterface} 742 * through the given {@code MBeanServerConnection}. 743 * 744 * @throws IllegalArgumentException if {@code mxbeanInterface} 745 * is not a platform management interface. 746 * 747 * @throws java.io.IOException if a communication problem 748 * occurred when accessing the {@code MBeanServerConnection}. 749 * 750 * @see #newPlatformMXBeanProxy 751 * @since 1.7 752 */ 753 public static <T extends PlatformManagedObject> 754 List<T> getPlatformMXBeans(MBeanServerConnection connection, 755 Class<T> mxbeanInterface) 756 throws java.io.IOException 757 { 758 PlatformComponent pc = PlatformComponent.getPlatformComponent(mxbeanInterface); 759 if (pc == null) { 760 throw new IllegalArgumentException(mxbeanInterface.getName() + 761 " is not a platform management interface"); 762 } 763 return Collections.unmodifiableList(pc.getMXBeans(connection, mxbeanInterface)); 764 } 765 766 /** 767 * Returns the set of {@code Class} objects, subinterface of 768 * {@link PlatformManagedObject}, representing 769 * all management interfaces for 770 * monitoring and managing the Java platform. 771 * 772 * @return the set of {@code Class} objects, subinterface of 773 * {@link PlatformManagedObject} representing 774 * the management interfaces for 775 * monitoring and managing the Java platform. 776 * 777 * @since 1.7 778 */ 779 public static Set<Class<? extends PlatformManagedObject>> 780 getPlatformManagementInterfaces() 781 { 782 Set<Class<? extends PlatformManagedObject>> result = 783 new TreeSet<>(); 784 for (PlatformComponent component: PlatformComponent.values()) { 785 result.add(component.getMXBeanInterface()); 786 } 787 return Collections.unmodifiableSet(result); 788 } 789 790 private static final String NOTIF_EMITTER = 791 "javax.management.NotificationEmitter"; 792 793 /** 794 * Registers an MXBean. 795 */ 796 private static void addMXBean(final MBeanServer mbs, final PlatformManagedObject pmo) { 797 // Make DynamicMBean out of MXBean by wrapping it with a StandardMBean 798 final DynamicMBean dmbean; 799 if (pmo instanceof DynamicMBean) { 800 dmbean = DynamicMBean.class.cast(pmo); 801 } else if (pmo instanceof NotificationEmitter) { 802 dmbean = new StandardEmitterMBean(pmo, null, true, (NotificationEmitter) pmo); 803 } else { 804 dmbean = new StandardMBean(pmo, null, true); 805 } 806 807 try { 808 AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() { 809 public Void run() throws InstanceAlreadyExistsException, 810 MBeanRegistrationException, 811 NotCompliantMBeanException { 812 mbs.registerMBean(dmbean, pmo.getObjectName()); 813 return null; 814 } 815 }); 816 } catch (PrivilegedActionException e) { 817 throw new RuntimeException(e.getException()); 818 } 819 } 820 821 }