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