1/* 2 * Copyright (c) 1999, 2017, 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 26package com.sun.jmx.mbeanserver; 27 28import com.sun.jmx.interceptor.DefaultMBeanServerInterceptor; 29import com.sun.jmx.interceptor.MBeanServerInterceptor; 30import static com.sun.jmx.defaults.JmxProperties.MBEANSERVER_LOGGER; 31 32import java.io.ObjectInputStream; 33import java.security.AccessController; 34import java.security.Permission; 35import java.security.PrivilegedAction; 36import java.security.PrivilegedExceptionAction; 37import java.util.List; 38import java.util.Set; 39import java.lang.System.Logger.Level; 40 41import javax.management.Attribute; 42import javax.management.AttributeList; 43import javax.management.AttributeNotFoundException; 44import javax.management.InstanceAlreadyExistsException; 45import javax.management.InstanceNotFoundException; 46import javax.management.IntrospectionException; 47import javax.management.InvalidAttributeValueException; 48import javax.management.ListenerNotFoundException; 49import javax.management.MBeanException; 50import javax.management.MBeanInfo; 51import javax.management.MBeanPermission; 52import javax.management.MBeanRegistrationException; 53import javax.management.MBeanServer; 54import javax.management.MBeanServerDelegate; 55import javax.management.MBeanServerPermission; 56import javax.management.NotCompliantMBeanException; 57import javax.management.NotificationFilter; 58import javax.management.NotificationListener; 59import javax.management.ObjectInstance; 60import javax.management.ObjectName; 61import javax.management.OperationsException; 62import javax.management.QueryExp; 63import javax.management.ReflectionException; 64import javax.management.RuntimeOperationsException; 65import javax.management.loading.ClassLoaderRepository; 66 67/** 68 * This is the base class for MBean manipulation on the agent side. It 69 * contains the methods necessary for the creation, registration, and 70 * deletion of MBeans as well as the access methods for registered MBeans. 71 * This is the core component of the JMX infrastructure. 72 * <P> 73 * Every MBean which is added to the MBean server becomes manageable: 74 * its attributes and operations become remotely accessible through 75 * the connectors/adaptors connected to that MBean server. 76 * A Java object cannot be registered in the MBean server unless it is a 77 * JMX compliant MBean. 78 * <P> 79 * When an MBean is registered or unregistered in the MBean server an 80 * {@link javax.management.MBeanServerNotification MBeanServerNotification} 81 * Notification is emitted. To register an object as listener to 82 * MBeanServerNotifications you should call the MBean server method 83 * {@link #addNotificationListener addNotificationListener} with 84 * the <CODE>ObjectName</CODE> of the 85 * {@link javax.management.MBeanServerDelegate MBeanServerDelegate}. 86 * This <CODE>ObjectName</CODE> is: 87 * <BR> 88 * <CODE>JMImplementation:type=MBeanServerDelegate</CODE>. 89 * 90 * @since 1.5 91 */ 92public final class JmxMBeanServer 93 implements SunJmxMBeanServer { 94 95 /** Control the default locking policy of the repository. 96 * By default, we will be using a fair locking policy. 97 **/ 98 public static final boolean DEFAULT_FAIR_LOCK_POLICY = true; 99 100 private final MBeanInstantiator instantiator; 101 private final SecureClassLoaderRepository secureClr; 102 103 /** true if interceptors are enabled **/ 104 private final boolean interceptorsEnabled; 105 106 private final MBeanServer outerShell; 107 108 private volatile MBeanServer mbsInterceptor = null; 109 110 /** The MBeanServerDelegate object representing the MBean Server */ 111 private final MBeanServerDelegate mBeanServerDelegateObject; 112 113 /** 114 * <b>Package:</b> Creates an MBeanServer with the 115 * specified default domain name, outer interface, and delegate. 116 * <p>The default domain name is used as the domain part in the ObjectName 117 * of MBeans if no domain is specified by the user. 118 * <ul><b>Note:</b>Using this constructor directly is strongly 119 * discouraged. You should use 120 * {@link javax.management.MBeanServerFactory#createMBeanServer(java.lang.String)} 121 * or 122 * {@link javax.management.MBeanServerFactory#newMBeanServer(java.lang.String)} 123 * instead. 124 * <p> 125 * By default, interceptors are disabled. Use 126 * {@link #JmxMBeanServer(java.lang.String,javax.management.MBeanServer,javax.management.MBeanServerDelegate,boolean)} to enable them. 127 * </ul> 128 * @param domain The default domain name used by this MBeanServer. 129 * @param outer A pointer to the MBeanServer object that must be 130 * passed to the MBeans when invoking their 131 * {@link javax.management.MBeanRegistration} interface. 132 * @param delegate A pointer to the MBeanServerDelegate associated 133 * with the new MBeanServer. The new MBeanServer must register 134 * this MBean in its MBean repository. 135 * @exception IllegalArgumentException if the instantiator is null. 136 */ 137 JmxMBeanServer(String domain, MBeanServer outer, 138 MBeanServerDelegate delegate) { 139 this(domain,outer,delegate,null,false); 140 } 141 142 /** 143 * <b>Package:</b> Creates an MBeanServer with the 144 * specified default domain name, outer interface, and delegate. 145 * <p>The default domain name is used as the domain part in the ObjectName 146 * of MBeans if no domain is specified by the user. 147 * <ul><b>Note:</b>Using this constructor directly is strongly 148 * discouraged. You should use 149 * {@link javax.management.MBeanServerFactory#createMBeanServer(java.lang.String)} 150 * or 151 * {@link javax.management.MBeanServerFactory#newMBeanServer(java.lang.String)} 152 * instead. 153 * </ul> 154 * @param domain The default domain name used by this MBeanServer. 155 * @param outer A pointer to the MBeanServer object that must be 156 * passed to the MBeans when invoking their 157 * {@link javax.management.MBeanRegistration} interface. 158 * @param delegate A pointer to the MBeanServerDelegate associated 159 * with the new MBeanServer. The new MBeanServer must register 160 * this MBean in its MBean repository. 161 * @param interceptors If <code>true</code>, 162 * {@link MBeanServerInterceptor} will be enabled (default is 163 * <code>false</code>) 164 * Note: this parameter is not taken into account by this 165 * implementation - the default value <code>false</code> is 166 * always used. 167 * @exception IllegalArgumentException if the instantiator is null. 168 */ 169 JmxMBeanServer(String domain, MBeanServer outer, 170 MBeanServerDelegate delegate, boolean interceptors) { 171 this(domain,outer,delegate,null,false); 172 } 173 174 /** 175 * <b>Package:</b> Creates an MBeanServer. 176 * @param domain The default domain name used by this MBeanServer. 177 * @param outer A pointer to the MBeanServer object that must be 178 * passed to the MBeans when invoking their 179 * {@link javax.management.MBeanRegistration} interface. 180 * @param delegate A pointer to the MBeanServerDelegate associated 181 * with the new MBeanServer. The new MBeanServer must register 182 * this MBean in its MBean repository. 183 * @param instantiator The MBeanInstantiator that will be used to 184 * instantiate MBeans and take care of class loading issues. 185 * @param metadata The MetaData object that will be used by the 186 * MBean server in order to invoke the MBean interface of 187 * the registered MBeans. 188 * @param interceptors If <code>true</code>, 189 * {@link MBeanServerInterceptor} will be enabled (default is 190 * <code>false</code>). 191 */ 192 JmxMBeanServer(String domain, MBeanServer outer, 193 MBeanServerDelegate delegate, 194 MBeanInstantiator instantiator, 195 boolean interceptors) { 196 this(domain,outer,delegate,instantiator,interceptors,true); 197 } 198 199 /** 200 * <b>Package:</b> Creates an MBeanServer. 201 * @param domain The default domain name used by this MBeanServer. 202 * @param outer A pointer to the MBeanServer object that must be 203 * passed to the MBeans when invoking their 204 * {@link javax.management.MBeanRegistration} interface. 205 * @param delegate A pointer to the MBeanServerDelegate associated 206 * with the new MBeanServer. The new MBeanServer must register 207 * this MBean in its MBean repository. 208 * @param instantiator The MBeanInstantiator that will be used to 209 * instantiate MBeans and take care of class loading issues. 210 * @param metadata The MetaData object that will be used by the 211 * MBean server in order to invoke the MBean interface of 212 * the registered MBeans. 213 * @param interceptors If <code>true</code>, 214 * {@link MBeanServerInterceptor} will be enabled (default is 215 * <code>false</code>). 216 * @param fairLock If {@code true}, the MBean repository will use a {@link 217 * java.util.concurrent.locks.ReentrantReadWriteLock#ReentrantReadWriteLock(boolean) 218 * fair locking} policy. 219 */ 220 JmxMBeanServer(String domain, MBeanServer outer, 221 MBeanServerDelegate delegate, 222 MBeanInstantiator instantiator, 223 boolean interceptors, 224 boolean fairLock) { 225 226 if (instantiator == null) { 227 final ModifiableClassLoaderRepository 228 clr = new ClassLoaderRepositorySupport(); 229 instantiator = new MBeanInstantiator(clr); 230 } 231 232 final MBeanInstantiator fInstantiator = instantiator; 233 this.secureClr = new 234 SecureClassLoaderRepository(AccessController.doPrivileged(new PrivilegedAction<ClassLoaderRepository>() { 235 @Override 236 public ClassLoaderRepository run() { 237 return fInstantiator.getClassLoaderRepository(); 238 } 239 }) 240 ); 241 if (delegate == null) 242 delegate = new MBeanServerDelegateImpl(); 243 if (outer == null) 244 outer = this; 245 246 this.instantiator = instantiator; 247 this.mBeanServerDelegateObject = delegate; 248 this.outerShell = outer; 249 250 final Repository repository = new Repository(domain); 251 this.mbsInterceptor = 252 new DefaultMBeanServerInterceptor(outer, delegate, instantiator, 253 repository); 254 this.interceptorsEnabled = interceptors; 255 initialize(); 256 } 257 258 /** 259 * Tell whether {@link MBeanServerInterceptor}s are enabled on this 260 * object. 261 * @return <code>true</code> if {@link MBeanServerInterceptor}s are 262 * enabled. 263 * @see #newMBeanServer(java.lang.String,javax.management.MBeanServer,javax.management.MBeanServerDelegate,boolean) 264 **/ 265 public boolean interceptorsEnabled() { 266 return interceptorsEnabled; 267 } 268 269 /** 270 * Return the MBeanInstantiator associated to this MBeanServer. 271 * @exception UnsupportedOperationException if 272 * {@link MBeanServerInterceptor}s 273 * are not enabled on this object. 274 * @see #interceptorsEnabled 275 **/ 276 public MBeanInstantiator getMBeanInstantiator() { 277 if (interceptorsEnabled) return instantiator; 278 else throw new UnsupportedOperationException( 279 "MBeanServerInterceptors are disabled."); 280 } 281 282 /** 283 * Instantiates and registers an MBean in the MBean server. 284 * The MBean server will use its 285 * {@link javax.management.loading.ClassLoaderRepository Default Loader Repository} 286 * to load the class of the MBean. 287 * An object name is associated to the MBean. 288 * If the object name given is null, the MBean can automatically 289 * provide its own name by implementing the 290 * {@link javax.management.MBeanRegistration MBeanRegistration} interface. 291 * The call returns an <CODE>ObjectInstance</CODE> object representing 292 * the newly created MBean. 293 * 294 * @param className The class name of the MBean to be instantiated. 295 * @param name The object name of the MBean. May be null. 296 * 297 * @return An <CODE>ObjectInstance</CODE>, containing the 298 * <CODE>ObjectName</CODE> and the Java class name of the newly 299 * instantiated MBean. 300 * 301 * @exception ReflectionException Wraps an 302 * <CODE>{@link java.lang.ClassNotFoundException}</CODE> or an 303 * <CODE>{@link java.lang.Exception}</CODE> that occurred 304 * when trying to invoke the MBean's constructor. 305 * @exception InstanceAlreadyExistsException The MBean is already 306 * under the control of the MBean server. 307 * @exception MBeanRegistrationException The <CODE>preRegister()</CODE> 308 * (<CODE>MBeanRegistration</CODE> interface) method of the MBean 309 * has thrown an exception. The MBean will not be registered. 310 * @exception MBeanException The constructor of the MBean has thrown 311 * an exception. 312 * @exception NotCompliantMBeanException This class is not a JMX 313 * compliant MBean. 314 * @exception RuntimeOperationsException Wraps an 315 * <CODE>{@link java.lang.IllegalArgumentException}</CODE>: 316 * The className passed in parameter is null, the 317 * <CODE>ObjectName</CODE> passed in parameter contains a pattern 318 * or no <CODE>ObjectName</CODE> is specified for the MBean. 319 * 320 */ 321 public ObjectInstance createMBean(String className, ObjectName name) 322 throws ReflectionException, InstanceAlreadyExistsException, 323 MBeanRegistrationException, MBeanException, 324 NotCompliantMBeanException { 325 326 return mbsInterceptor.createMBean(className, 327 cloneObjectName(name), 328 (Object[]) null, 329 (String[]) null); 330 } 331 332 /** 333 * Instantiates and registers an MBean in the MBean server. 334 * The class loader to be used is identified by its object name. 335 * An object name is associated to the MBean. 336 * If the object name of the loader is null, the ClassLoader that 337 * loaded the MBean server will be used. 338 * If the MBean's object name given is null, the MBean can 339 * automatically provide its own name by implementing the 340 * {@link javax.management.MBeanRegistration MBeanRegistration} interface. 341 * The call returns an <CODE>ObjectInstance</CODE> object representing 342 * the newly created MBean. 343 * 344 * @param className The class name of the MBean to be instantiated. 345 * @param name The object name of the MBean. May be null. 346 * @param loaderName The object name of the class loader to be used. 347 * 348 * @return An <CODE>ObjectInstance</CODE>, containing the 349 * <CODE>ObjectName</CODE> and the Java class name 350 * of the newly instantiated MBean. 351 * 352 * @exception ReflectionException Wraps an 353 * <CODE>{@link java.lang.ClassNotFoundException}</CODE> or an 354 * <CODE>{@link java.lang.Exception}</CODE> that occurred when trying 355 * to invoke the MBean's constructor. 356 * @exception InstanceAlreadyExistsException The MBean is already 357 * under the control of the MBean server. 358 * @exception MBeanRegistrationException The <CODE>preRegister()</CODE> 359 * (<CODE>MBeanRegistration</CODE> interface) method of the MBean 360 * has thrown an exception. The MBean will not be registered. 361 * @exception MBeanException The constructor of the MBean has thrown 362 * an exception 363 * @exception NotCompliantMBeanException This class is not a JMX 364 * compliant MBean. 365 * @exception InstanceNotFoundException The specified class loader 366 * is not registered in the MBean server. 367 * @exception RuntimeOperationsException Wraps an 368 * <CODE>{@link java.lang.IllegalArgumentException}</CODE>: The 369 * className passed in parameter is null, the <CODE>ObjectName</CODE> 370 * passed in parameter contains a pattern or no 371 * <CODE>ObjectName</CODE> is specified for the MBean. 372 */ 373 public ObjectInstance createMBean(String className, ObjectName name, 374 ObjectName loaderName) 375 throws ReflectionException, InstanceAlreadyExistsException, 376 MBeanRegistrationException, MBeanException, 377 NotCompliantMBeanException, InstanceNotFoundException { 378 379 return mbsInterceptor.createMBean(className, 380 cloneObjectName(name), 381 loaderName, 382 (Object[]) null, 383 (String[]) null); 384 } 385 386 /** 387 * Instantiates and registers an MBean in the MBean server. 388 * The MBean server will use its 389 * {@link javax.management.loading.ClassLoaderRepository Default Loader Repository} 390 * to load the class of the MBean. 391 * An object name is associated to the MBean. 392 * If the object name given is null, the MBean can automatically 393 * provide its own name by implementing the 394 * {@link javax.management.MBeanRegistration MBeanRegistration} interface. 395 * The call returns an <CODE>ObjectInstance</CODE> object representing 396 * the newly created MBean. 397 * 398 * @param className The class name of the MBean to be instantiated. 399 * @param name The object name of the MBean. May be null. 400 * @param params An array containing the parameters of the constructor 401 * to be invoked. 402 * @param signature An array containing the signature of the 403 * constructor to be invoked. 404 * 405 * @return An <CODE>ObjectInstance</CODE>, containing the 406 * <CODE>ObjectName</CODE> and the Java class name 407 * of the newly instantiated MBean. 408 * 409 * @exception ReflectionException Wraps a 410 * <CODE>{@link java.lang.ClassNotFoundException}</CODE> or an 411 * <CODE>{@link java.lang.Exception}</CODE> that occurred 412 * when trying to invoke the MBean's constructor. 413 * @exception InstanceAlreadyExistsException The MBean is already 414 * under the control of the MBean server. 415 * @exception MBeanRegistrationException The <CODE>preRegister()</CODE> 416 * (<CODE>MBeanRegistration</CODE> interface) method of the MBean 417 * has thrown an exception. The MBean will not be registered. 418 * @exception MBeanException The constructor of the MBean has 419 * thrown an exception. 420 * @exception RuntimeOperationsException Wraps an 421 * <CODE>{@link java.lang.IllegalArgumentException}</CODE>: The 422 * className passed in parameter is null, the <CODE>ObjectName</CODE> 423 * passed in parameter contains a pattern or no 424 * <CODE>ObjectName</CODE> is specified for the MBean. 425 * 426 */ 427 public ObjectInstance createMBean(String className, ObjectName name, 428 Object params[], String signature[]) 429 throws ReflectionException, InstanceAlreadyExistsException, 430 MBeanRegistrationException, MBeanException, 431 NotCompliantMBeanException { 432 433 return mbsInterceptor.createMBean(className, cloneObjectName(name), 434 params, signature); 435 } 436 437 /** 438 * Instantiates and registers an MBean in the MBean server. 439 * The class loader to be used is identified by its object name. 440 * An object name is associated to the MBean. If the object name 441 * of the loader is not specified, the ClassLoader that loaded the 442 * MBean server will be used. 443 * If the MBean object name given is null, the MBean can automatically 444 * provide its own name by implementing the 445 * {@link javax.management.MBeanRegistration MBeanRegistration} interface. 446 * The call returns an <CODE>ObjectInstance</CODE> object representing 447 * the newly created MBean. 448 * 449 * @param className The class name of the MBean to be instantiated. 450 * @param name The object name of the MBean. May be null. 451 * @param params An array containing the parameters of the constructor 452 * to be invoked. 453 * @param signature An array containing the signature of the 454 * constructor to be invoked. 455 * @param loaderName The object name of the class loader to be used. 456 * 457 * @return An <CODE>ObjectInstance</CODE>, containing the 458 * <CODE>ObjectName</CODE> and the Java class name of the newly 459 * instantiated MBean. 460 * 461 * @exception ReflectionException Wraps a 462 * <CODE>{@link java.lang.ClassNotFoundException}</CODE> or an 463 * <CODE>{@link java.lang.Exception}</CODE> 464 * that occurred when trying to invoke the MBean's constructor. 465 * @exception InstanceAlreadyExistsException The MBean is already 466 * under the control of the MBean server. 467 * @exception MBeanRegistrationException The <CODE>preRegister()</CODE> 468 * (<CODE>MBeanRegistration</CODE> interface) method of the MBean 469 * has thrown an exception. The MBean will not be registered. 470 * @exception MBeanException The constructor of the MBean has 471 * thrown an exception 472 * @exception InstanceNotFoundException The specified class loader is 473 * not registered in the MBean server. 474 * @exception RuntimeOperationsException Wraps an 475 * <CODE>{@link java.lang.IllegalArgumentException}</CODE>: The 476 * className passed in parameter is null, the <CODE>ObjectName</CODE> 477 * passed in parameter contains a pattern or no 478 * <CODE>ObjectName</CODE> is specified for the MBean. 479 * 480 */ 481 public ObjectInstance createMBean(String className, ObjectName name, 482 ObjectName loaderName, Object params[], 483 String signature[]) 484 throws ReflectionException, InstanceAlreadyExistsException, 485 MBeanRegistrationException, MBeanException, 486 NotCompliantMBeanException, InstanceNotFoundException { 487 488 return mbsInterceptor.createMBean(className, cloneObjectName(name), 489 loaderName, params, signature); 490 } 491 492 /** 493 * Registers a pre-existing object as an MBean with the MBean server. 494 * If the object name given is null, the MBean may automatically 495 * provide its own name by implementing the 496 * {@link javax.management.MBeanRegistration MBeanRegistration} interface. 497 * The call returns an <CODE>ObjectInstance</CODE> object representing 498 * the registered MBean. 499 * 500 * @param object The MBean to be registered as an MBean. 501 * @param name The object name of the MBean. May be null. 502 * 503 * @return The <CODE>ObjectInstance</CODE> for the MBean that has been 504 * registered. 505 * 506 * @exception InstanceAlreadyExistsException The MBean is already 507 * under the control of the MBean server. 508 * @exception MBeanRegistrationException The <CODE>preRegister()</CODE> 509 * (<CODE>MBeanRegistration</CODE> interface) method of the MBean 510 * has thrown an exception. The MBean will not be registered. 511 * @exception NotCompliantMBeanException This object is not a JMX 512 * compliant MBean 513 * @exception RuntimeOperationsException Wraps an 514 * <CODE>{@link java.lang.IllegalArgumentException}</CODE>: The 515 * object passed in parameter is null or no object name is specified. 516 * 517 */ 518 public ObjectInstance registerMBean(Object object, ObjectName name) 519 throws InstanceAlreadyExistsException, MBeanRegistrationException, 520 NotCompliantMBeanException { 521 522 return mbsInterceptor.registerMBean(object, cloneObjectName(name)); 523 } 524 525 /** 526 * De-registers an MBean from the MBean server. The MBean is identified by 527 * its object name. Once the method has been invoked, the MBean may 528 * no longer be accessed by its object name. 529 * 530 * @param name The object name of the MBean to be de-registered. 531 * 532 * @exception InstanceNotFoundException The MBean specified is not 533 * registered in the MBean server. 534 * @exception MBeanRegistrationException The <code>preDeregister()</code> 535 * (<CODE>MBeanRegistration</CODE> interface) method of the MBean 536 * has thrown an exception. 537 * @exception RuntimeOperationsException Wraps an 538 * <CODE>{@link java.lang.IllegalArgumentException}</CODE>: The 539 * object name in parameter is null or the MBean you are when 540 * trying to de-register is the 541 * {@link javax.management.MBeanServerDelegate MBeanServerDelegate} 542 * MBean. 543 **/ 544 public void unregisterMBean(ObjectName name) 545 throws InstanceNotFoundException, MBeanRegistrationException { 546 mbsInterceptor.unregisterMBean(cloneObjectName(name)); 547 } 548 549 /** 550 * Gets the <CODE>ObjectInstance</CODE> for a given MBean registered 551 * with the MBean server. 552 * 553 * @param name The object name of the MBean. 554 * 555 * @return The <CODE>ObjectInstance</CODE> associated to the MBean 556 * specified by <VAR>name</VAR>. 557 * 558 * @exception InstanceNotFoundException The MBean specified is not 559 * registered in the MBean server. 560 */ 561 public ObjectInstance getObjectInstance(ObjectName name) 562 throws InstanceNotFoundException { 563 564 return mbsInterceptor.getObjectInstance(cloneObjectName(name)); 565 } 566 567 /** 568 * Gets MBeans controlled by the MBean server. This method allows any 569 * of the following to be obtained: All MBeans, a set of MBeans specified 570 * by pattern matching on the <CODE>ObjectName</CODE> and/or a Query 571 * expression, a specific MBean. When the object name is null or no 572 * domain and key properties are specified, all objects are to be 573 * selected (and filtered if a query is specified). It returns the 574 * set of <CODE>ObjectInstance</CODE> objects (containing the 575 * <CODE>ObjectName</CODE> and the Java Class name) for 576 * the selected MBeans. 577 * 578 * @param name The object name pattern identifying the MBeans to 579 * be retrieved. If null or no domain and key properties 580 * are specified, all the MBeans registered will be retrieved. 581 * @param query The query expression to be applied for selecting 582 * MBeans. If null no query expression will be applied for 583 * selecting MBeans. 584 * 585 * @return A set containing the <CODE>ObjectInstance</CODE> objects 586 * for the selected MBeans. 587 * If no MBean satisfies the query an empty list is returned. 588 * 589 */ 590 public Set<ObjectInstance> queryMBeans(ObjectName name, QueryExp query) { 591 592 return mbsInterceptor.queryMBeans(cloneObjectName(name), query); 593 } 594 595 /** 596 * Gets the names of MBeans controlled by the MBean server. This method 597 * enables any of the following to be obtained: The names of all MBeans, 598 * the names of a set of MBeans specified by pattern matching on the 599 * <CODE>ObjectName</CODE> and/or a Query expression, a specific 600 * MBean name (equivalent to testing whether an MBean is registered). 601 * When the object name is null or no domain and key properties are 602 * specified, all objects are selected (and filtered if a query is 603 * specified). It returns the set of ObjectNames for the MBeans 604 * selected. 605 * 606 * @param name The object name pattern identifying the MBeans to be 607 * retrieved. If null or no domain and key properties are 608 * specified, all the MBeans registered will be retrieved. 609 * @param query The query expression to be applied for selecting 610 * MBeans. If null no query expression will be applied for 611 * selecting MBeans. 612 * 613 * @return A set containing the ObjectNames for the MBeans selected. 614 * If no MBean satisfies the query, an empty list is returned. 615 * 616 */ 617 public Set<ObjectName> queryNames(ObjectName name, QueryExp query) { 618 619 return mbsInterceptor.queryNames(cloneObjectName(name), query); 620 } 621 622 /** 623 * Checks whether an MBean, identified by its object name, is already 624 * registered with the MBean server. 625 * 626 * @param name The object name of the MBean to be checked. 627 * 628 * @return True if the MBean is already registered in the MBean server, 629 * false otherwise. 630 * 631 * @exception RuntimeOperationsException Wraps an 632 * <CODE>{@link java.lang.IllegalArgumentException}</CODE>: The object 633 * name in parameter is null. 634 * 635 */ 636 public boolean isRegistered(ObjectName name) { 637 638 return mbsInterceptor.isRegistered(name); 639 } 640 641 /** 642 * Returns the number of MBeans registered in the MBean server. 643 */ 644 public Integer getMBeanCount() { 645 646 return mbsInterceptor.getMBeanCount(); 647 } 648 649 /** 650 * Gets the value of a specific attribute of a named MBean. The MBean 651 * is identified by its object name. 652 * 653 * @param name The object name of the MBean from which the attribute 654 * is to be retrieved. 655 * @param attribute A String specifying the name of the attribute to be 656 * retrieved. 657 * 658 * @return The value of the retrieved attribute. 659 * 660 * @exception AttributeNotFoundException The attribute specified 661 * is not accessible in the MBean. 662 * @exception MBeanException Wraps an exception thrown by the 663 * MBean's getter. 664 * @exception InstanceNotFoundException The MBean specified is not 665 * registered in the MBean server. 666 * @exception ReflectionException Wraps an 667 * <CODE>{@link java.lang.Exception}</CODE> thrown when trying to 668 * invoke the setter. 669 * @exception RuntimeOperationsException Wraps an 670 * <CODE>{@link java.lang.IllegalArgumentException}</CODE>: 671 * The object name in parameter is null or the attribute in 672 * parameter is null. 673 */ 674 public Object getAttribute(ObjectName name, String attribute) 675 throws MBeanException, AttributeNotFoundException, 676 InstanceNotFoundException, ReflectionException { 677 678 return mbsInterceptor.getAttribute(cloneObjectName(name), attribute); 679 } 680 681 682 /** 683 * Enables the values of several attributes of a named MBean. The MBean 684 * is identified by its object name. 685 * 686 * @param name The object name of the MBean from which the attributes are 687 * retrieved. 688 * @param attributes A list of the attributes to be retrieved. 689 * 690 * @return The list of the retrieved attributes. 691 * 692 * @exception InstanceNotFoundException The MBean specified is not 693 * registered in the MBean server. 694 * @exception ReflectionException An exception occurred when trying 695 * to invoke the getAttributes method of a Dynamic MBean. 696 * @exception RuntimeOperationsException Wrap an 697 * <CODE>{@link java.lang.IllegalArgumentException}</CODE>: The 698 * object name in parameter is null or attributes in parameter 699 * is null. 700 * 701 */ 702 public AttributeList getAttributes(ObjectName name, String[] attributes) 703 throws InstanceNotFoundException, ReflectionException { 704 705 return mbsInterceptor.getAttributes(cloneObjectName(name), attributes); 706 707 } 708 709 /** 710 * Sets the value of a specific attribute of a named MBean. The MBean 711 * is identified by its object name. 712 * 713 * @param name The name of the MBean within which the attribute is 714 * to be set. 715 * @param attribute The identification of the attribute to be set 716 * and the value it is to be set to. 717 * 718 * @exception InstanceNotFoundException The MBean specified is 719 * not registered in the MBean server. 720 * @exception AttributeNotFoundException The attribute specified is 721 * not accessible in the MBean. 722 * @exception InvalidAttributeValueException The value specified for 723 * the attribute is not valid. 724 * @exception MBeanException Wraps an exception thrown by the 725 * MBean's setter. 726 * @exception ReflectionException Wraps an 727 * <CODE>{@link java.lang.Exception}</CODE> thrown when trying 728 * to invoke the setter. 729 * @exception RuntimeOperationsException Wraps an 730 * <CODE>{@link java.lang.IllegalArgumentException}</CODE>: The 731 * object name in parameter is null or the attribute in parameter 732 * is null. 733 */ 734 public void setAttribute(ObjectName name, Attribute attribute) 735 throws InstanceNotFoundException, AttributeNotFoundException, 736 InvalidAttributeValueException, MBeanException, 737 ReflectionException { 738 739 mbsInterceptor.setAttribute(cloneObjectName(name), 740 cloneAttribute(attribute)); 741 } 742 743 /** 744 * Sets the values of several attributes of a named MBean. The MBean is 745 * identified by its object name. 746 * 747 * @param name The object name of the MBean within which the 748 * attributes are to be set. 749 * @param attributes A list of attributes: The identification of the 750 * attributes to be set and the values they are to be set to. 751 * 752 * @return The list of attributes that were set, with their new values. 753 * 754 * @exception InstanceNotFoundException The MBean specified is not 755 * registered in the MBean server. 756 * @exception ReflectionException An exception occurred when trying 757 * to invoke the getAttributes method of a Dynamic MBean. 758 * @exception RuntimeOperationsException Wraps an 759 * <CODE>{@link java.lang.IllegalArgumentException}</CODE>: 760 * The object name in parameter is null or attributes in 761 * parameter is null. 762 * 763 */ 764 public AttributeList setAttributes(ObjectName name, 765 AttributeList attributes) 766 throws InstanceNotFoundException, ReflectionException { 767 768 return mbsInterceptor.setAttributes(cloneObjectName(name), 769 cloneAttributeList(attributes)); 770 } 771 772 /** 773 * Invokes an operation on an MBean. 774 * 775 * @param name The object name of the MBean on which the method is to be 776 * invoked. 777 * @param operationName The name of the operation to be invoked. 778 * @param params An array containing the parameters to be set when 779 * the operation is invoked 780 * @param signature An array containing the signature of the operation. 781 * The class objects will be loaded using the same class loader as 782 * the one used for loading the MBean on which the operation was 783 * invoked. 784 * 785 * @return The object returned by the operation, which represents the 786 * result ofinvoking the operation on the MBean specified. 787 * 788 * @exception InstanceNotFoundException The MBean specified is not 789 * registered in the MBean server. 790 * @exception MBeanException Wraps an exception thrown by the MBean's 791 * invoked method. 792 * @exception ReflectionException Wraps an 793 * <CODE>{@link java.lang.Exception}</CODE> thrown while trying 794 * to invoke the method. 795 * 796 */ 797 public Object invoke(ObjectName name, String operationName, 798 Object params[], String signature[]) 799 throws InstanceNotFoundException, MBeanException, 800 ReflectionException { 801 return mbsInterceptor.invoke(cloneObjectName(name), operationName, 802 params, signature); 803 } 804 805 /** 806 * Returns the default domain used for naming the MBean. 807 * The default domain name is used as the domain part in the ObjectName 808 * of MBeans if no domain is specified by the user. 809 */ 810 public String getDefaultDomain() { 811 return mbsInterceptor.getDefaultDomain(); 812 } 813 814 // From MBeanServer 815 public String[] getDomains() { 816 return mbsInterceptor.getDomains(); 817 } 818 819 /** 820 * Adds a listener to a registered MBean. 821 * 822 * @param name The name of the MBean on which the listener should be added. 823 * @param listener The listener object which will handle the 824 * notifications emitted by the registered MBean. 825 * @param filter The filter object. If filter is null, no filtering 826 * will be performed before handling notifications. 827 * @param handback The context to be sent to the listener when a 828 * notification is emitted. 829 * 830 * @exception InstanceNotFoundException The MBean name provided does 831 * not match any of the registered MBeans. 832 */ 833 public void addNotificationListener(ObjectName name, 834 NotificationListener listener, 835 NotificationFilter filter, 836 Object handback) 837 throws InstanceNotFoundException { 838 839 mbsInterceptor.addNotificationListener(cloneObjectName(name), listener, 840 filter, handback); 841 } 842 843 /** 844 * Adds a listener to a registered MBean. 845 * 846 * @param name The name of the MBean on which the listener should be added. 847 * @param listener The object name of the listener which will handle the 848 * notifications emitted by the registered MBean. 849 * @param filter The filter object. If filter is null, no filtering will 850 * be performed before handling notifications. 851 * @param handback The context to be sent to the listener when a 852 * notification is emitted. 853 * 854 * @exception InstanceNotFoundException The MBean name of the 855 * notification listener or of the notification broadcaster 856 * does not match any of the registered MBeans. 857 */ 858 public void addNotificationListener(ObjectName name, ObjectName listener, 859 NotificationFilter filter, Object handback) 860 throws InstanceNotFoundException { 861 862 mbsInterceptor.addNotificationListener(cloneObjectName(name), listener, 863 filter, handback); 864 } 865 866 public void removeNotificationListener(ObjectName name, 867 NotificationListener listener) 868 throws InstanceNotFoundException, ListenerNotFoundException { 869 870 mbsInterceptor.removeNotificationListener(cloneObjectName(name), 871 listener); 872 } 873 874 public void removeNotificationListener(ObjectName name, 875 NotificationListener listener, 876 NotificationFilter filter, 877 Object handback) 878 throws InstanceNotFoundException, ListenerNotFoundException { 879 880 mbsInterceptor.removeNotificationListener(cloneObjectName(name), 881 listener, filter, handback); 882 } 883 884 public void removeNotificationListener(ObjectName name, 885 ObjectName listener) 886 throws InstanceNotFoundException, ListenerNotFoundException { 887 888 mbsInterceptor.removeNotificationListener(cloneObjectName(name), 889 listener); 890 } 891 892 public void removeNotificationListener(ObjectName name, 893 ObjectName listener, 894 NotificationFilter filter, 895 Object handback) 896 throws InstanceNotFoundException, ListenerNotFoundException { 897 898 mbsInterceptor.removeNotificationListener(cloneObjectName(name), 899 listener, filter, handback); 900 } 901 902 /** 903 * This method discovers the attributes and operations that an MBean exposes 904 * for management. 905 * 906 * @param name The name of the MBean to analyze 907 * 908 * @return An instance of <CODE>MBeanInfo</CODE> allowing the retrieval of 909 * all attributes and operations of this MBean. 910 * 911 * @exception IntrospectionException An exception occurs during 912 * introspection. 913 * @exception InstanceNotFoundException The MBean specified is not found. 914 * @exception ReflectionException An exception occurred when trying to 915 * invoke the getMBeanInfo of a Dynamic MBean. 916 */ 917 public MBeanInfo getMBeanInfo(ObjectName name) throws 918 InstanceNotFoundException, IntrospectionException, ReflectionException { 919 920 return mbsInterceptor.getMBeanInfo(cloneObjectName(name)); 921 } 922 923 /** 924 * Instantiates an object using the list of all class loaders registered 925 * in the MBean server (using its 926 * {@link javax.management.loading.ClassLoaderRepository Default Loader Repository}). 927 * The object's class should have a public constructor. 928 * It returns a reference to the newly created object. 929 * The newly created object is not registered in the MBean server. 930 * 931 * @param className The class name of the object to be instantiated. 932 * 933 * @return The newly instantiated object. 934 * 935 * @exception ReflectionException Wraps the 936 * <CODE>{@link java.lang.ClassNotFoundException}</CODE> or the 937 * <CODE>{@link java.lang.Exception}</CODE> that 938 * occurred when trying to invoke the object's constructor. 939 * @exception MBeanException The constructor of the object has thrown 940 * an exception. 941 * @exception RuntimeOperationsException Wraps an 942 * <CODE>{@link java.lang.IllegalArgumentException}</CODE>: 943 * The className passed in parameter is null. 944 * 945 */ 946 public Object instantiate(String className) 947 throws ReflectionException, MBeanException { 948 949 /* Permission check */ 950 checkMBeanPermission(className, null, null, "instantiate"); 951 952 return instantiator.instantiate(className); 953 } 954 955 /** 956 * Instantiates an object using the class Loader specified by its 957 * <CODE>ObjectName</CODE>. 958 * If the loader name is null, the ClassLoader that loaded the 959 * MBean Server will be used. 960 * The object's class should have a public constructor. 961 * It returns a reference to the newly created object. 962 * The newly created object is not registered in the MBean server. 963 * 964 * @param className The class name of the MBean to be instantiated. 965 * @param loaderName The object name of the class loader to be used. 966 * 967 * @return The newly instantiated object. 968 * 969 * @exception ReflectionException Wraps the 970 * <CODE>{@link java.lang.ClassNotFoundException}</CODE> or the 971 * <CODE>{@link java.lang.Exception}</CODE> that 972 * occurred when trying to invoke the object's constructor. 973 * @exception MBeanException The constructor of the object has thrown 974 * an exception. 975 * @exception InstanceNotFoundException The specified class loader 976 * is not registered in the MBaenServer. 977 * @exception RuntimeOperationsException Wraps an 978 * <CODE>{@link java.lang.IllegalArgumentException}</CODE>: The 979 * className passed in parameter is null. 980 * 981 */ 982 public Object instantiate(String className, ObjectName loaderName) 983 throws ReflectionException, MBeanException, 984 InstanceNotFoundException { 985 986 /* Permission check */ 987 checkMBeanPermission(className, null, null, "instantiate"); 988 989 ClassLoader myLoader = outerShell.getClass().getClassLoader(); 990 return instantiator.instantiate(className, loaderName, myLoader); 991 } 992 993 /** 994 * Instantiates an object using the list of all class loaders registered 995 * in the MBean server (using its 996 * {@link javax.management.loading.ClassLoaderRepository Default Loader Repository}). 997 * The object's class should have a public constructor. 998 * The call returns a reference to the newly created object. 999 * The newly created object is not registered in the MBean server. 1000 * 1001 * @param className The class name of the object to be instantiated. 1002 * @param params An array containing the parameters of the constructor 1003 * to be invoked. 1004 * @param signature An array containing the signature of the 1005 * constructor to be invoked. 1006 * 1007 * @return The newly instantiated object. 1008 * 1009 * @exception ReflectionException Wraps the 1010 * <CODE>{@link java.lang.ClassNotFoundException}</CODE> or the 1011 * <CODE>{@link java.lang.Exception}</CODE> that 1012 * occurred when trying to invoke the object's constructor. 1013 * @exception MBeanException The constructor of the object has thrown 1014 * an exception. 1015 * @exception RuntimeOperationsException Wraps an 1016 * <CODE>{@link java.lang.IllegalArgumentException}</CODE>: 1017 * The className passed in parameter is null. 1018 * 1019 */ 1020 public Object instantiate(String className, Object params[], 1021 String signature[]) 1022 throws ReflectionException, MBeanException { 1023 1024 /* Permission check */ 1025 checkMBeanPermission(className, null, null, "instantiate"); 1026 1027 ClassLoader myLoader = outerShell.getClass().getClassLoader(); 1028 return instantiator.instantiate(className, params, signature, 1029 myLoader); 1030 } 1031 1032 /** 1033 * Instantiates an object. The class loader to be used is identified 1034 * by its object name. If the object name of the loader is null, 1035 * the ClassLoader that loaded the MBean server will be used. 1036 * The object's class should have a public constructor. 1037 * The call returns a reference to the newly created object. 1038 * The newly created object is not registered in the MBean server. 1039 * 1040 * @param className The class name of the object to be instantiated. 1041 * @param params An array containing the parameters of the constructor 1042 * to be invoked. 1043 * @param signature An array containing the signature of the constructor 1044 * to be invoked. 1045 * @param loaderName The object name of the class loader to be used. 1046 * 1047 * @return The newly instantiated object. 1048 * 1049 * @exception ReflectionException Wraps the 1050 * <CODE>{@link java.lang.ClassNotFoundException}</CODE> or the 1051 * <CODE>{@link java.lang.Exception}</CODE> that 1052 * occurred when trying to invoke the object's constructor. 1053 * @exception MBeanException The constructor of the object has thrown 1054 * an exception. 1055 * @exception InstanceNotFoundException The specified class loader 1056 * is not registered in the MBean server. 1057 * @exception RuntimeOperationsException Wraps an 1058 * <CODE>{@link java.lang.IllegalArgumentException}</CODE>: 1059 * The className passed in parameter is null. 1060 * 1061 */ 1062 public Object instantiate(String className, ObjectName loaderName, 1063 Object params[], String signature[]) 1064 throws ReflectionException, MBeanException, 1065 InstanceNotFoundException { 1066 1067 /* Permission check */ 1068 checkMBeanPermission(className, null, null, "instantiate"); 1069 1070 ClassLoader myLoader = outerShell.getClass().getClassLoader(); 1071 return instantiator.instantiate(className,loaderName,params,signature, 1072 myLoader); 1073 } 1074 1075 /** 1076 * Returns true if the MBean specified is an instance of the specified 1077 * class, false otherwise. 1078 * 1079 * @param name The <CODE>ObjectName</CODE> of the MBean. 1080 * @param className The name of the class. 1081 * 1082 * @return true if the MBean specified is an instance of the specified 1083 * class, false otherwise. 1084 * 1085 * @exception InstanceNotFoundException The MBean specified is not 1086 * registered in the MBean server. 1087 */ 1088 public boolean isInstanceOf(ObjectName name, String className) 1089 throws InstanceNotFoundException { 1090 1091 return mbsInterceptor.isInstanceOf(cloneObjectName(name), className); 1092 } 1093 1094 /** 1095 * De-serializes a byte array in the context of the class loader 1096 * of an MBean. 1097 * 1098 * @param name The name of the MBean whose class loader should 1099 * be used for the de-serialization. 1100 * @param data The byte array to be de-sererialized. 1101 * 1102 * @return The de-serialized object stream. 1103 * 1104 * @exception InstanceNotFoundException The MBean specified is not 1105 * found. 1106 * @exception OperationsException Any of the usual Input/Output 1107 * related exceptions. 1108 * 1109 */ 1110 @Deprecated 1111 public ObjectInputStream deserialize(ObjectName name, byte[] data) 1112 throws InstanceNotFoundException, OperationsException { 1113 1114 /* Permission check */ 1115 // This call requires MBeanPermission 'getClassLoaderFor' 1116 final ClassLoader loader = getClassLoaderFor(name); 1117 1118 return instantiator.deserialize(loader, data); 1119 } 1120 1121 /** 1122 * De-serializes a byte array in the context of a given MBean class loader. 1123 * The class loader is the one that loaded the class with name "className". 1124 * 1125 * @param className The name of the class whose class loader should be 1126 * used for the de-serialization. 1127 * @param data The byte array to be de-sererialized. 1128 * 1129 * @return The de-serialized object stream. 1130 * 1131 * @exception OperationsException Any of the usual Input/Output 1132 * related exceptions. 1133 * @exception ReflectionException The specified class could not be 1134 * loaded by the default loader repository 1135 * 1136 */ 1137 @Deprecated 1138 public ObjectInputStream deserialize(String className, byte[] data) 1139 throws OperationsException, ReflectionException { 1140 1141 if (className == null) { 1142 throw new RuntimeOperationsException( 1143 new IllegalArgumentException(), 1144 "Null className passed in parameter"); 1145 } 1146 1147 /* Permission check */ 1148 // This call requires MBeanPermission 'getClassLoaderRepository' 1149 final ClassLoaderRepository clr = getClassLoaderRepository(); 1150 1151 Class<?> theClass; 1152 try { 1153 if (clr == null) throw new ClassNotFoundException(className); 1154 theClass = clr.loadClass(className); 1155 } catch (ClassNotFoundException e) { 1156 throw new ReflectionException(e, 1157 "The given class could not be " + 1158 "loaded by the default loader " + 1159 "repository"); 1160 } 1161 1162 return instantiator.deserialize(theClass.getClassLoader(), data); 1163 } 1164 1165 /** 1166 * De-serializes a byte array in the context of a given MBean class loader. 1167 * The class loader is the one that loaded the class with name "className". 1168 * The name of the class loader to be used for loading the specified 1169 * class is specified. 1170 * If null, the MBean Server's class loader will be used. 1171 * 1172 * @param className The name of the class whose class loader should be 1173 * used for the de-serialization. 1174 * @param data The byte array to be de-sererialized. 1175 * @param loaderName The name of the class loader to be used for 1176 * loading the specified class. 1177 * If null, the MBean Server's class loader will be used. 1178 * 1179 * @return The de-serialized object stream. 1180 * 1181 * @exception InstanceNotFoundException The specified class loader 1182 * MBean is not found. 1183 * @exception OperationsException Any of the usual Input/Output 1184 * related exceptions. 1185 * @exception ReflectionException The specified class could not 1186 * be loaded by the specified class loader. 1187 * 1188 */ 1189 @Deprecated 1190 public ObjectInputStream deserialize(String className, 1191 ObjectName loaderName, 1192 byte[] data) throws 1193 InstanceNotFoundException, OperationsException, ReflectionException { 1194 1195 // Clone ObjectName 1196 // 1197 loaderName = cloneObjectName(loaderName); 1198 1199 /* Permission check */ 1200 // Make this call just to force the 'getClassLoader' 1201 // permission check 1202 try { 1203 getClassLoader(loaderName); 1204 } catch (SecurityException e) { 1205 throw e; 1206 } catch (Exception e) { 1207 } 1208 1209 ClassLoader myLoader = outerShell.getClass().getClassLoader(); 1210 return instantiator.deserialize(className, loaderName, data, myLoader); 1211 } 1212 1213 /** 1214 * Initializes this MBeanServer, registering the MBeanServerDelegate. 1215 * <p>This method must be called once, before using the MBeanServer. 1216 **/ 1217 private void initialize() { 1218 if (instantiator == null) throw new 1219 IllegalStateException("instantiator must not be null."); 1220 1221 // Registers the MBeanServer identification MBean 1222 try { 1223 AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() { 1224 public Object run() throws Exception { 1225 mbsInterceptor.registerMBean( 1226 mBeanServerDelegateObject, 1227 MBeanServerDelegate.DELEGATE_NAME); 1228 return null; 1229 } 1230 }); 1231 } catch (SecurityException e) { 1232 if (MBEANSERVER_LOGGER.isLoggable(Level.DEBUG)) { 1233 MBEANSERVER_LOGGER.log(Level.DEBUG, 1234 "Unexpected security exception occurred", e); 1235 } 1236 throw e; 1237 } catch (Exception e) { 1238 if (MBEANSERVER_LOGGER.isLoggable(Level.DEBUG)) { 1239 MBEANSERVER_LOGGER.log(Level.DEBUG, 1240 "Unexpected exception occurred", e); 1241 } 1242 throw new 1243 IllegalStateException("Can't register delegate.",e); 1244 } 1245 1246 1247 /* Add my class loader to the repository 1248 This can be null if my class loader is the bootstrap 1249 class loader. The ClassLoaderRepository knows how 1250 to handle that case. */ 1251 ClassLoader myLoader = outerShell.getClass().getClassLoader(); 1252 final ModifiableClassLoaderRepository loaders = AccessController.doPrivileged(new PrivilegedAction<ModifiableClassLoaderRepository>() { 1253 1254 @Override 1255 public ModifiableClassLoaderRepository run() { 1256 return instantiator.getClassLoaderRepository(); 1257 } 1258 }); 1259 1260 if (loaders != null) { 1261 loaders.addClassLoader(myLoader); 1262 1263 /* Add the system class loader, so that if the MBean server is 1264 loaded by the bootstrap class loader we can still load 1265 MBeans from the classpath using 1266 createMBean(className, objectName). 1267 1268 If this class (JmxMBeanServer) was not loaded by the 1269 system class loader or a parent of it, then the caller 1270 must have RuntimePermission("getClassLoader") for the 1271 getSystemClassLoader() call to succeed. If the caller 1272 does not have that permission, any call to 1273 Class.getClassLoader() will fail. Since there are lots 1274 of those in JMX, we better throw the exception now. 1275 1276 This permission question is irrelevant when JMX is part 1277 of J2SE (as of 1.5). */ 1278 ClassLoader systemLoader = ClassLoader.getSystemClassLoader(); 1279 if (systemLoader != myLoader) 1280 loaders.addClassLoader(systemLoader); 1281 } 1282 } 1283 1284 /** 1285 * Return the MBeanServerInterceptor. 1286 * @exception UnsupportedOperationException if 1287 * {@link MBeanServerInterceptor}s 1288 * are not enabled on this object. 1289 * @see #interceptorsEnabled 1290 **/ 1291 public synchronized MBeanServer getMBeanServerInterceptor() { 1292 if (interceptorsEnabled) return mbsInterceptor; 1293 else throw new UnsupportedOperationException( 1294 "MBeanServerInterceptors are disabled."); 1295 } 1296 1297 /** 1298 * Set the MBeanServerInterceptor. 1299 * @exception UnsupportedOperationException if 1300 * {@link MBeanServerInterceptor}s 1301 * are not enabled on this object. 1302 * @see #interceptorsEnabled 1303 **/ 1304 public synchronized void 1305 setMBeanServerInterceptor(MBeanServer interceptor) { 1306 if (!interceptorsEnabled) throw new UnsupportedOperationException( 1307 "MBeanServerInterceptors are disabled."); 1308 if (interceptor == null) throw new 1309 IllegalArgumentException("MBeanServerInterceptor is null"); 1310 mbsInterceptor = interceptor; 1311 } 1312 1313 /** 1314 * <p>Return the {@link java.lang.ClassLoader} that was used for 1315 * loading the class of the named MBean. 1316 * @param mbeanName The ObjectName of the MBean. 1317 * @return The ClassLoader used for that MBean. 1318 * @exception InstanceNotFoundException if the named MBean is not found. 1319 */ 1320 public ClassLoader getClassLoaderFor(ObjectName mbeanName) 1321 throws InstanceNotFoundException { 1322 return mbsInterceptor.getClassLoaderFor(cloneObjectName(mbeanName)); 1323 } 1324 1325 /** 1326 * <p>Return the named {@link java.lang.ClassLoader}. 1327 * @param loaderName The ObjectName of the ClassLoader. 1328 * @return The named ClassLoader. 1329 * @exception InstanceNotFoundException if the named ClassLoader 1330 * is not found. 1331 */ 1332 public ClassLoader getClassLoader(ObjectName loaderName) 1333 throws InstanceNotFoundException { 1334 return mbsInterceptor.getClassLoader(cloneObjectName(loaderName)); 1335 } 1336 1337 /** 1338 * <p>Return the ClassLoaderRepository for that MBeanServer. 1339 * @return The ClassLoaderRepository for that MBeanServer. 1340 **/ 1341 public ClassLoaderRepository getClassLoaderRepository() { 1342 /* Permission check */ 1343 checkMBeanPermission(null, null, null, "getClassLoaderRepository"); 1344 return secureClr; 1345 } 1346 1347 public MBeanServerDelegate getMBeanServerDelegate() { 1348 if (!interceptorsEnabled) throw new UnsupportedOperationException( 1349 "MBeanServerInterceptors are disabled."); 1350 return mBeanServerDelegateObject; 1351 } 1352 1353 // These methods are called by the JMX MBeanServerBuilder. 1354 1355 /** 1356 * This method creates a new MBeanServerDelegate for a new MBeanServer. 1357 * When creating a new MBeanServer the 1358 * {@link javax.management.MBeanServerBuilder} first calls this method 1359 * in order to create a new MBeanServerDelegate. 1360 * <br>Then it calls 1361 * <code>newMBeanServer(defaultDomain,outer,delegate,interceptors)</code> 1362 * passing the <var>delegate</var> that should be used by the MBeanServer 1363 * implementation. 1364 * <p>Note that the passed <var>delegate</var> might not be directly the 1365 * MBeanServerDelegate that was returned by this method. It could 1366 * be, for instance, a new object wrapping the previously 1367 * returned object. 1368 * 1369 * @return A new {@link javax.management.MBeanServerDelegate}. 1370 **/ 1371 public static MBeanServerDelegate newMBeanServerDelegate() { 1372 return new MBeanServerDelegateImpl(); 1373 } 1374 1375 /** 1376 * This method creates a new MBeanServer implementation object. 1377 * When creating a new MBeanServer the 1378 * {@link javax.management.MBeanServerBuilder} first calls 1379 * <code>newMBeanServerDelegate()</code> in order to obtain a new 1380 * {@link javax.management.MBeanServerDelegate} for the new 1381 * MBeanServer. Then it calls 1382 * <code>newMBeanServer(defaultDomain,outer,delegate)</code> 1383 * passing the <var>delegate</var> that should be used by the 1384 * MBeanServer implementation. 1385 * <p>Note that the passed <var>delegate</var> might not be directly the 1386 * MBeanServerDelegate that was returned by this implementation. It could 1387 * be, for instance, a new object wrapping the previously 1388 * returned delegate. 1389 * <p>The <var>outer</var> parameter is a pointer to the MBeanServer that 1390 * should be passed to the {@link javax.management.MBeanRegistration} 1391 * interface when registering MBeans inside the MBeanServer. 1392 * If <var>outer</var> is <code>null</code>, then the MBeanServer 1393 * implementation is free to use its own <code>this</code> pointer when 1394 * invoking the {@link javax.management.MBeanRegistration} interface. 1395 * <p>This makes it possible for a MBeanServer implementation to wrap 1396 * another MBeanServer implementation, in order to implement, e.g, 1397 * security checks, or to prevent access to the actual MBeanServer 1398 * implementation by returning a pointer to a wrapping object. 1399 * 1400 * @param defaultDomain Default domain of the new MBeanServer. 1401 * @param outer A pointer to the MBeanServer object that must be 1402 * passed to the MBeans when invoking their 1403 * {@link javax.management.MBeanRegistration} interface. 1404 * @param delegate A pointer to the MBeanServerDelegate associated 1405 * with the new MBeanServer. The new MBeanServer must register 1406 * this MBean in its MBean repository. 1407 * @param interceptors If <code>true</code>, 1408 * {@link MBeanServerInterceptor}s will be enabled (default is 1409 * <code>false</code>). 1410 * Note: this parameter is not taken into account by this 1411 * implementation - the default value <code>false</code> is 1412 * always used. 1413 * @return A new private implementation of an MBeanServer. 1414 * @see #interceptorsEnabled 1415 * @see javax.management.MBeanServerBuilder 1416 * @see com.sun.jmx.mbeanserver.JmxMBeanServerBuilder 1417 **/ 1418 public static MBeanServer newMBeanServer(String defaultDomain, 1419 MBeanServer outer, 1420 MBeanServerDelegate delegate, 1421 boolean interceptors) { 1422 // Determine whether to use fair locking for the repository. 1423 // Default is true. 1424 final boolean fairLock = DEFAULT_FAIR_LOCK_POLICY; 1425 1426 checkNewMBeanServerPermission(); 1427 1428 // This constructor happens to disregard the value of the interceptors 1429 // flag - that is, it always uses the default value - false. 1430 // This is admitedly a bug, but we chose not to fix it for now 1431 // since we would rather not have anybody depending on the Sun private 1432 // interceptor APIs - which is most probably going to be removed and 1433 // replaced by a public (javax) feature in the future. 1434 // 1435 return new JmxMBeanServer(defaultDomain,outer,delegate,null, 1436 interceptors,fairLock); 1437 } 1438 1439 // JMX OBJECT CLONING 1440 //------------------- 1441 1442 /** 1443 * Clone object name. 1444 */ 1445 private ObjectName cloneObjectName(ObjectName name) { 1446 if (name != null) { 1447 return ObjectName.getInstance(name); 1448 } 1449 return name; 1450 } 1451 1452 /** 1453 * Clone attribute. 1454 */ 1455 private Attribute cloneAttribute(Attribute attribute) { 1456 if (attribute != null) { 1457 if (!attribute.getClass().equals(Attribute.class)) { 1458 return new Attribute(attribute.getName(), attribute.getValue()); 1459 } 1460 } 1461 return attribute; 1462 } 1463 1464 /** 1465 * Clone attribute list. 1466 */ 1467 private AttributeList cloneAttributeList(AttributeList list) { 1468 if (list != null) { 1469 List<Attribute> alist = list.asList(); 1470 if (!list.getClass().equals(AttributeList.class)) { 1471 // Create new attribute list 1472 // 1473 AttributeList newList = new AttributeList(alist.size()); 1474 1475 // Iterate through list and replace non JMX attributes 1476 // 1477 for (Attribute attribute : alist) 1478 newList.add(cloneAttribute(attribute)); 1479 return newList; 1480 } else { 1481 // Iterate through list and replace non JMX attributes 1482 // 1483 for (int i = 0; i < alist.size(); i++) { 1484 Attribute attribute = alist.get(i); 1485 if (!attribute.getClass().equals(Attribute.class)) { 1486 list.set(i, cloneAttribute(attribute)); 1487 } 1488 } 1489 return list; 1490 } 1491 } 1492 return list; 1493 } 1494 1495 // SECURITY CHECKS 1496 //---------------- 1497 1498 private static void checkMBeanPermission(String classname, 1499 String member, 1500 ObjectName objectName, 1501 String actions) 1502 throws SecurityException { 1503 SecurityManager sm = System.getSecurityManager(); 1504 if (sm != null) { 1505 Permission perm = new MBeanPermission(classname, 1506 member, 1507 objectName, 1508 actions); 1509 sm.checkPermission(perm); 1510 } 1511 } 1512 1513 private static void checkNewMBeanServerPermission() { 1514 SecurityManager sm = System.getSecurityManager(); 1515 if (sm != null) { 1516 Permission perm = new MBeanServerPermission("newMBeanServer"); 1517 sm.checkPermission(perm); 1518 } 1519 } 1520} 1521