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