Frames | No Frames |
1: /* Server.java -- A GNU Classpath management server. 2: Copyright (C) 2006 Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: package gnu.javax.management; 39: 40: import java.io.ByteArrayInputStream; 41: import java.io.InputStream; 42: import java.io.IOException; 43: import java.io.ObjectInputStream; 44: import java.io.ObjectStreamClass; 45: import java.io.StreamCorruptedException; 46: 47: import java.lang.reflect.Constructor; 48: import java.lang.reflect.InvocationTargetException; 49: import java.lang.reflect.Method; 50: 51: import java.util.HashMap; 52: import java.util.HashSet; 53: import java.util.Iterator; 54: import java.util.Map; 55: import java.util.Set; 56: import java.util.concurrent.atomic.AtomicLong; 57: 58: import javax.management.Attribute; 59: import javax.management.AttributeList; 60: import javax.management.AttributeNotFoundException; 61: import javax.management.BadAttributeValueExpException; 62: import javax.management.BadBinaryOpValueExpException; 63: import javax.management.BadStringOperationException; 64: import javax.management.DynamicMBean; 65: import javax.management.InstanceAlreadyExistsException; 66: import javax.management.InstanceNotFoundException; 67: import javax.management.IntrospectionException; 68: import javax.management.InvalidApplicationException; 69: import javax.management.InvalidAttributeValueException; 70: import javax.management.ListenerNotFoundException; 71: import javax.management.MalformedObjectNameException; 72: import javax.management.MBeanException; 73: import javax.management.MBeanInfo; 74: import javax.management.MBeanPermission; 75: import javax.management.MBeanRegistration; 76: import javax.management.MBeanRegistrationException; 77: import javax.management.MBeanServer; 78: import javax.management.MBeanServerDelegate; 79: import javax.management.MBeanServerNotification; 80: import javax.management.MBeanTrustPermission; 81: import javax.management.NotCompliantMBeanException; 82: import javax.management.Notification; 83: import javax.management.NotificationBroadcaster; 84: import javax.management.NotificationEmitter; 85: import javax.management.NotificationFilter; 86: import javax.management.NotificationListener; 87: import javax.management.ObjectInstance; 88: import javax.management.ObjectName; 89: import javax.management.OperationsException; 90: import javax.management.QueryExp; 91: import javax.management.ReflectionException; 92: import javax.management.RuntimeOperationsException; 93: import javax.management.StandardMBean; 94: 95: import javax.management.loading.ClassLoaderRepository; 96: 97: /** 98: * This class provides an {@link javax.management.MBeanServer} 99: * implementation for GNU Classpath. 100: * 101: * @author Andrew John Hughes (gnu_andrew@member.fsf.org) 102: * @since 1.5 103: */ 104: public class Server 105: implements MBeanServer 106: { 107: 108: /** 109: * The name of the delegate bean. 110: */ 111: private static final ObjectName DELEGATE_NAME; 112: 113: /** 114: * The registered beans, represented as a map of 115: * {@link javax.management.ObjectName}s to 116: * {@link java.lang.Object}s. 117: */ 118: private final Map beans = new HashMap(); 119: 120: /** 121: * The default domain. 122: */ 123: private String defaultDomain; 124: 125: /** 126: * The outer server. 127: */ 128: private MBeanServer outer; 129: 130: /** 131: * The class loader repository. 132: */ 133: private ClassLoaderRepository repository; 134: 135: /** 136: * The map of listener delegates to the true 137: * listener. 138: */ 139: private Map listeners; 140: 141: /** 142: * An MBean that emits notifications when an MBean is registered and 143: * unregistered with this server. 144: * 145: */ 146: private final MBeanServerDelegate delegate; 147: 148: static private final AtomicLong sequenceNumber = new AtomicLong(1); 149: 150: /** 151: * Initialise the delegate name. 152: */ 153: static 154: { 155: try 156: { 157: DELEGATE_NAME = 158: new ObjectName("JMImplementation:type=MBeanServerDelegate"); 159: } 160: catch (MalformedObjectNameException e) 161: { 162: throw (Error) 163: (new InternalError("Failed to construct " + 164: "the delegate's object name.").initCause(e)); 165: } 166: } 167: 168: /** 169: * Constructs a new management server using the specified 170: * default domain, delegate bean and outer server. 171: * 172: * @param domain the default domain to use for beans constructed 173: * with no specified domain. 174: * @param outer an {@link javax.management.MBeanServer} to pass 175: * to beans implementing the {@link MBeanRegistration} 176: * interface, or <code>null</code> if <code>this</code> 177: * should be passed. 178: * @param delegate the delegate bean for this server. 179: */ 180: public Server(String defaultDomain, MBeanServer outer, 181: MBeanServerDelegate delegate) 182: { 183: this.defaultDomain = defaultDomain; 184: this.outer = outer; 185: this.delegate = delegate; 186: try 187: { 188: registerMBean(delegate, DELEGATE_NAME); 189: } 190: catch (InstanceAlreadyExistsException e) 191: { 192: throw (Error) 193: (new InternalError("The delegate bean is " + 194: "already registered.").initCause(e)); 195: } 196: catch (MBeanRegistrationException e) 197: { 198: throw (Error) 199: (new InternalError("The delegate bean's preRegister " + 200: "methods threw an exception.").initCause(e)); 201: } 202: catch (NotCompliantMBeanException e) 203: { 204: throw (Error) 205: (new InternalError("The delegate bean is " + 206: "not compliant.").initCause(e)); 207: } 208: } 209: 210: /** 211: * Checks for the necessary security privileges to perform an 212: * operation. 213: * 214: * @param name the name of the bean being accessed. 215: * @param member the name of the operation or attribute being 216: * accessed, or <code>null</code> if one is not 217: * involved. 218: * @param action the action being performed. 219: * @throws SecurityException if the action is denied. 220: */ 221: private void checkSecurity(ObjectName name, String member, 222: String action) 223: { 224: SecurityManager sm = System.getSecurityManager(); 225: if (sm != null) 226: try 227: { 228: MBeanInfo info = null; 229: if (name != null) 230: { 231: Object bean = getBean(name); 232: Method method = bean.getClass().getMethod("getMBeanInfo", null); 233: info = (MBeanInfo) method.invoke(bean, null); 234: } 235: sm.checkPermission(new MBeanPermission((info == null) ? 236: null : info.getClassName(), 237: member, name, action)); 238: } 239: catch (InstanceNotFoundException e) 240: { 241: throw (Error) 242: (new InternalError("Failed to get bean.").initCause(e)); 243: } 244: catch (NoSuchMethodException e) 245: { 246: throw (Error) 247: (new InternalError("Failed to get bean info.").initCause(e)); 248: } 249: catch (IllegalAccessException e) 250: { 251: throw (Error) 252: (new InternalError("Failed to get bean info.").initCause(e)); 253: } 254: catch (IllegalArgumentException e) 255: { 256: throw (Error) 257: (new InternalError("Failed to get bean info.").initCause(e)); 258: } 259: catch (InvocationTargetException e) 260: { 261: throw (Error) 262: (new InternalError("Failed to get bean info.").initCause(e)); 263: } 264: } 265: 266: /** 267: * Retrieves the specified bean. 268: * 269: * @param name the name of the bean. 270: * @return the bean. 271: * @throws InstanceNotFoundException if the name of the management bean 272: * could not be resolved. 273: */ 274: private Object getBean(ObjectName name) 275: throws InstanceNotFoundException 276: { 277: ServerInfo bean = (ServerInfo) beans.get(name); 278: if (bean == null) 279: throw new InstanceNotFoundException("The bean, " + name + 280: ", was not found."); 281: return bean.getObject(); 282: } 283: 284: /** 285: * Registers the supplied listener with the specified management 286: * bean. Notifications emitted by the management bean are forwarded 287: * to the listener via the server, which will convert an MBean 288: * references in the source to a portable {@link ObjectName} 289: * instance. The notification is otherwise unchanged. 290: * 291: * @param name the name of the management bean with which the listener 292: * should be registered. 293: * @param listener the listener which will handle notifications from 294: * the bean. 295: * @param filter the filter to apply to incoming notifications, or 296: * <code>null</code> if no filtering should be applied. 297: * @param passback an object to be passed to the listener when a 298: * notification is emitted. 299: * @throws InstanceNotFoundException if the name of the management bean 300: * could not be resolved. 301: * @throws SecurityException if a security manager exists and the 302: * caller's permissions don't imply {@link 303: * MBeanPermission(String,String,ObjectName,String) 304: * <code>MBeanPermission(className, null, name, 305: * "addNotificationListener")</code>}. 306: * @see #removeNotificationListener(ObjectName, NotificationListener) 307: * @see #removeNotificationListener(ObjectName, NotificationListener, 308: * NotificationFilter, Object) 309: * @see NotificationBroadcaster#addNotificationListener(NotificationListener, 310: * NotificationFilter, 311: * Object) 312: */ 313: public void addNotificationListener(ObjectName name, NotificationListener listener, 314: NotificationFilter filter, Object passback) 315: throws InstanceNotFoundException 316: { 317: Object bean = getBean(name); 318: checkSecurity(name, null, "addNotificationListener"); 319: if (bean instanceof NotificationBroadcaster) 320: { 321: NotificationBroadcaster bbean = (NotificationBroadcaster) bean; 322: if (listeners == null) 323: listeners = new HashMap(); 324: NotificationListener indirection = new ServerNotificationListener(bean, name, 325: listener); 326: bbean.addNotificationListener(indirection, filter, passback); 327: listeners.put(listener, indirection); 328: } 329: } 330: 331: /** 332: * <p> 333: * Registers the supplied listener with the specified management 334: * bean. Notifications emitted by the management bean are forwarded 335: * to the listener via the server, which will convert any MBean 336: * references in the source to portable {@link ObjectName} 337: * instances. The notification is otherwise unchanged. 338: * </p> 339: * <p> 340: * The listener that receives notifications will be the one that is 341: * registered with the given name at the time this method is called. 342: * Even if it later unregisters and ceases to use that name, it will 343: * still receive notifications. 344: * </p> 345: * 346: * @param name the name of the management bean with which the listener 347: * should be registered. 348: * @param listener the name of the listener which will handle 349: * notifications from the bean. 350: * @param filter the filter to apply to incoming notifications, or 351: * <code>null</code> if no filtering should be applied. 352: * @param passback an object to be passed to the listener when a 353: * notification is emitted. 354: * @throws InstanceNotFoundException if the name of the management bean 355: * could not be resolved. 356: * @throws RuntimeOperationsException if the bean associated with the given 357: * object name is not a 358: * {@link NotificationListener}. This 359: * exception wraps an 360: * {@link IllegalArgumentException}. 361: * @throws SecurityException if a security manager exists and the 362: * caller's permissions don't imply {@link 363: * MBeanPermission(String,String,ObjectName,String) 364: * <code>MBeanPermission(className, null, name, 365: * "addNotificationListener")</code>}. 366: * @see #removeNotificationListener(ObjectName, NotificationListener) 367: * @see #removeNotificationListener(ObjectName, NotificationListener, 368: * NotificationFilter, Object) 369: * @see NotificationBroadcaster#addNotificationListener(NotificationListener, 370: * NotificationFilter, 371: * Object) 372: */ 373: public void addNotificationListener(ObjectName name, ObjectName listener, 374: NotificationFilter filter, Object passback) 375: throws InstanceNotFoundException 376: { 377: Object lbean = getBean(listener); 378: if (!(lbean instanceof NotificationListener)) 379: { 380: RuntimeException e = 381: new IllegalArgumentException("The supplied listener name does not " + 382: "correspond to a notification listener."); 383: throw new RuntimeOperationsException(e); 384: } 385: addNotificationListener(name, ((NotificationListener) lbean), filter, passback); 386: } 387: 388: /** 389: * <p> 390: * Instantiates a new instance of the specified management bean 391: * using the default constructor and registers it with the server 392: * under the supplied name. The class is loaded using the 393: * {@link javax.management.loading.ClassLoaderRepository default 394: * loader repository} of the server. 395: * </p> 396: * <p> 397: * If the name supplied is <code>null</code>, then the bean is 398: * expected to implement the {@link MBeanRegistration} interface. 399: * The {@link MBeanRegistration#preRegister preRegister} method 400: * of this interface will be used to obtain the name in this case. 401: * </p> 402: * <p> 403: * This method is equivalent to calling {@link 404: * #createMBean(String, ObjectName, Object[], String[]) 405: * <code>createMBean(className, name, (Object[]) null, 406: * (String[]) null)</code>} with <code>null</code> parameters 407: * and signature. 408: * </p> 409: * 410: * @param className the class of the management bean, of which 411: * an instance should be created. 412: * @param name the name to register the new bean with. 413: * @return an {@link ObjectInstance} containing the {@link ObjectName} 414: * and Java class name of the created instance. 415: * @throws ReflectionException if an exception occurs in creating 416: * an instance of the bean. 417: * @throws InstanceAlreadyExistsException if a matching instance 418: * already exists. 419: * @throws MBeanRegistrationException if an exception occurs in 420: * calling the preRegister 421: * method. 422: * @throws MBeanException if the bean's constructor throws an exception. 423: * @throws NotCompliantMBeanException if the created bean is not 424: * compliant with the JMX specification. 425: * @throws RuntimeOperationsException if an {@link IllegalArgumentException} 426: * is thrown by the server due to a 427: * <code>null</code> class name or object 428: * name or if the object name is a pattern. 429: * @throws SecurityException if a security manager exists and the 430: * caller's permissions don't imply the 431: * use of the <code>instantiate</code> 432: * and <code>registerMBean</code> methods. 433: * @see #createMBean(String, ObjectName, Object[], String[]) 434: */ 435: public ObjectInstance createMBean(String className, ObjectName name) 436: throws ReflectionException, InstanceAlreadyExistsException, 437: MBeanRegistrationException, MBeanException, 438: NotCompliantMBeanException 439: { 440: return createMBean(className, name, (Object[]) null, (String[]) null); 441: } 442: 443: /** 444: * <p> 445: * Instantiates a new instance of the specified management bean 446: * using the given constructor and registers it with the server 447: * under the supplied name. The class is loaded using the 448: * {@link javax.management.loading.ClassLoaderRepository default 449: * loader repository} of the server. 450: * </p> 451: * <p> 452: * If the name supplied is <code>null</code>, then the bean is 453: * expected to implement the {@link MBeanRegistration} interface. 454: * The {@link MBeanRegistration#preRegister preRegister} method 455: * of this interface will be used to obtain the name in this case. 456: * </p> 457: * 458: * @param className the class of the management bean, of which 459: * an instance should be created. 460: * @param name the name to register the new bean with. 461: * @param params the parameters for the bean's constructor. 462: * @param sig the signature of the constructor to use. 463: * @return an {@link ObjectInstance} containing the {@link ObjectName} 464: * and Java class name of the created instance. 465: * @throws ReflectionException if an exception occurs in creating 466: * an instance of the bean. 467: * @throws InstanceAlreadyExistsException if a matching instance 468: * already exists. 469: * @throws MBeanRegistrationException if an exception occurs in 470: * calling the preRegister 471: * method. 472: * @throws MBeanException if the bean's constructor throws an exception. 473: * @throws NotCompliantMBeanException if the created bean is not 474: * compliant with the JMX specification. 475: * @throws RuntimeOperationsException if an {@link IllegalArgumentException} 476: * is thrown by the server due to a 477: * <code>null</code> class name or object 478: * name or if the object name is a pattern. 479: * @throws SecurityException if a security manager exists and the 480: * caller's permissions don't imply the 481: * use of the <code>instantiate</code> 482: * and <code>registerMBean</code> methods. 483: */ 484: public ObjectInstance createMBean(String className, ObjectName name, 485: Object[] params, String[] sig) 486: throws ReflectionException, InstanceAlreadyExistsException, 487: MBeanRegistrationException, MBeanException, 488: NotCompliantMBeanException 489: { 490: return registerMBean(instantiate(className, params, sig), name); 491: } 492: 493: /** 494: * <p> 495: * Instantiates a new instance of the specified management bean 496: * using the default constructor and registers it with the server 497: * under the supplied name. The class is loaded using the 498: * given class loader. If this argument is <code>null</code>, 499: * then the same class loader as was used to load the server 500: * is used. 501: * </p> 502: * <p> 503: * If the name supplied is <code>null</code>, then the bean is 504: * expected to implement the {@link MBeanRegistration} interface. 505: * The {@link MBeanRegistration#preRegister preRegister} method 506: * of this interface will be used to obtain the name in this case. 507: * </p> 508: * <p> 509: * This method is equivalent to calling {@link 510: * #createMBean(String, ObjectName, ObjectName, Object[], String) 511: * <code>createMBean(className, name, loaderName, (Object[]) null, 512: * (String) null)</code>} with <code>null</code> parameters 513: * and signature. 514: * </p> 515: * 516: * @param className the class of the management bean, of which 517: * an instance should be created. 518: * @param name the name to register the new bean with. 519: * @param loaderName the name of the class loader. 520: * @return an {@link ObjectInstance} containing the {@link ObjectName} 521: * and Java class name of the created instance. 522: * @throws ReflectionException if an exception occurs in creating 523: * an instance of the bean. 524: * @throws InstanceAlreadyExistsException if a matching instance 525: * already exists. 526: * @throws MBeanRegistrationException if an exception occurs in 527: * calling the preRegister 528: * method. 529: * @throws MBeanException if the bean's constructor throws an exception. 530: * @throws NotCompliantMBeanException if the created bean is not 531: * compliant with the JMX specification. 532: * @throws InstanceNotFoundException if the specified class loader is not 533: * registered with the server. 534: * @throws RuntimeOperationsException if an {@link IllegalArgumentException} 535: * is thrown by the server due to a 536: * <code>null</code> class name or object 537: * name or if the object name is a pattern. 538: * @throws SecurityException if a security manager exists and the 539: * caller's permissions don't imply the 540: * use of the <code>instantiate</code> 541: * and <code>registerMBean</code> methods. 542: * @see #createMBean(String, ObjectName, ObjectName, Object[], String[]) 543: */ 544: public ObjectInstance createMBean(String className, ObjectName name, 545: ObjectName loaderName) 546: throws ReflectionException, InstanceAlreadyExistsException, 547: MBeanRegistrationException, MBeanException, 548: NotCompliantMBeanException, InstanceNotFoundException 549: { 550: return createMBean(className, name, loaderName, (Object[]) null, 551: (String[]) null); 552: } 553: 554: /** 555: * <p> 556: * Instantiates a new instance of the specified management bean 557: * using the given constructor and registers it with the server 558: * under the supplied name. The class is loaded using the 559: * given class loader. If this argument is <code>null</code>, 560: * then the same class loader as was used to load the server 561: * is used. 562: * </p> 563: * <p> 564: * If the name supplied is <code>null</code>, then the bean is 565: * expected to implement the {@link MBeanRegistration} interface. 566: * The {@link MBeanRegistration#preRegister preRegister} method 567: * of this interface will be used to obtain the name in this case. 568: * </p> 569: * 570: * @param className the class of the management bean, of which 571: * an instance should be created. 572: * @param name the name to register the new bean with. 573: * @param loaderName the name of the class loader. 574: * @param params the parameters for the bean's constructor. 575: * @param sig the signature of the constructor to use. 576: * @return an {@link ObjectInstance} containing the {@link ObjectName} 577: * and Java class name of the created instance. 578: * @throws ReflectionException if an exception occurs in creating 579: * an instance of the bean. 580: * @throws InstanceAlreadyExistsException if a matching instance 581: * already exists. 582: * @throws MBeanRegistrationException if an exception occurs in 583: * calling the preRegister 584: * method. 585: * @throws MBeanException if the bean's constructor throws an exception. 586: * @throws NotCompliantMBeanException if the created bean is not 587: * compliant with the JMX specification. 588: * @throws InstanceNotFoundException if the specified class loader is not 589: * registered with the server. 590: * @throws RuntimeOperationsException if an {@link IllegalArgumentException} 591: * is thrown by the server due to a 592: * <code>null</code> class name or object 593: * name or if the object name is a pattern. 594: * @throws SecurityException if a security manager exists and the 595: * caller's permissions don't imply the 596: * use of the <code>instantiate</code> 597: * and <code>registerMBean</code> methods. 598: */ 599: public ObjectInstance createMBean(String className, ObjectName name, 600: ObjectName loaderName, Object[] params, 601: String[] sig) 602: throws ReflectionException, InstanceAlreadyExistsException, 603: MBeanRegistrationException, MBeanException, 604: NotCompliantMBeanException, InstanceNotFoundException 605: { 606: return registerMBean(instantiate(className, loaderName, params, sig), 607: name); 608: } 609: 610: /** 611: * Deserializes a byte array using the class loader of the specified 612: * management bean as its context. 613: * 614: * @param name the name of the bean whose class loader should be used. 615: * @param data the byte array to be deserialized. 616: * @return the deserialized object stream. 617: * @deprecated {@link #getClassLoaderFor(ObjectName)} should be used 618: * to obtain the class loader of the bean, which can then 619: * be used to perform deserialization in the user's code. 620: * @throws InstanceNotFoundException if the specified bean is not 621: * registered with the server. 622: * @throws OperationsException if any I/O error is thrown by the 623: * deserialization process. 624: * @throws SecurityException if a security manager exists and the 625: * caller's permissions don't imply {@link 626: * MBeanPermission(String,String,ObjectName,String) 627: * <code>MBeanPermission(className, null, name, 628: * "getClassLoaderFor")</code> 629: */ 630: public ObjectInputStream deserialize(ObjectName name, byte[] data) 631: throws InstanceNotFoundException, OperationsException 632: { 633: try 634: { 635: return new ServerInputStream(new ByteArrayInputStream(data), 636: getClassLoaderFor(name)); 637: } 638: catch (IOException e) 639: { 640: throw new OperationsException("An I/O error occurred: " + e); 641: } 642: } 643: 644: /** 645: * Deserializes a byte array using the same class loader for its context 646: * as was used to load the given class. This class loader is obtained by 647: * loading the specified class using the {@link 648: * javax.management.loading.ClassLoaderRepository Class Loader Repository} 649: * and then using the class loader of the resulting {@link Class} instance. 650: * 651: * @param name the name of the class which should be loaded to obtain the 652: * class loader. 653: * @param data the byte array to be deserialized. 654: * @return the deserialized object stream. 655: * @deprecated {@link #getClassLoaderRepository} should be used 656: * to obtain the class loading repository, which can then 657: * be used to obtain the {@link Class} instance and deserialize 658: * the array using its class loader. 659: * @throws OperationsException if any I/O error is thrown by the 660: * deserialization process. 661: * @throws ReflectionException if an error occurs in obtaining the 662: * {@link Class} instance. 663: * @throws SecurityException if a security manager exists and the 664: * caller's permissions don't imply {@link 665: * MBeanPermission(String,String,ObjectName,String) 666: * <code>MBeanPermission(null, null, null, 667: * "getClassLoaderRepository")</code> 668: */ 669: public ObjectInputStream deserialize(String name, byte[] data) 670: throws OperationsException, ReflectionException 671: { 672: try 673: { 674: Class c = getClassLoaderRepository().loadClass(name); 675: return new ServerInputStream(new ByteArrayInputStream(data), 676: c.getClassLoader()); 677: } 678: catch (IOException e) 679: { 680: throw new OperationsException("An I/O error occurred: " + e); 681: } 682: catch (ClassNotFoundException e) 683: { 684: throw new ReflectionException(e, "The class could not be found."); 685: } 686: } 687: 688: /** 689: * Deserializes a byte array using the same class loader for its context 690: * as was used to load the given class. The name of the class loader to 691: * be used is supplied, and may be <code>null</code> if the server's 692: * class loader should be used instead. 693: * 694: * @param name the name of the class which should be loaded to obtain the 695: * class loader. 696: * @param loader the name of the class loader to use, or <code>null</code> 697: * if the class loader of the server should be used. 698: * @param data the byte array to be deserialized. 699: * @return the deserialized object stream. 700: * @deprecated {@link #getClassLoader(ObjectName} can be used to obtain 701: * the named class loader and deserialize the array. 702: * @throws InstanceNotFoundException if the specified class loader is not 703: * registered with the server. 704: * @throws OperationsException if any I/O error is thrown by the 705: * deserialization process. 706: * @throws ReflectionException if an error occurs in obtaining the 707: * {@link Class} instance. 708: * @throws SecurityException if a security manager exists and the 709: * caller's permissions don't imply {@link 710: * MBeanPermission(String,String,ObjectName,String) 711: * <code>MBeanPermission(className, null, loader, 712: * "getClassLoader")</code> 713: */ 714: public ObjectInputStream deserialize(String name, ObjectName loader, byte[] data) 715: throws InstanceNotFoundException, ReflectionException, 716: OperationsException 717: { 718: try 719: { 720: Class c = getClassLoader(loader).loadClass(name); 721: return new ServerInputStream(new ByteArrayInputStream(data), 722: c.getClassLoader()); 723: } 724: catch (IOException e) 725: { 726: throw new OperationsException("An I/O error occurred: " + e); 727: } 728: catch (ClassNotFoundException e) 729: { 730: throw new ReflectionException(e, "The class could not be found."); 731: } 732: } 733: 734: /** 735: * Returns the value of the supplied attribute from the specified 736: * management bean. 737: * 738: * @param bean the bean to retrieve the value from. 739: * @param name the name of the attribute to retrieve. 740: * @return the value of the attribute. 741: * @throws AttributeNotFoundException if the attribute could not be 742: * accessed from the bean. 743: * @throws MBeanException if the management bean's accessor throws 744: * an exception. 745: * @throws InstanceNotFoundException if the bean can not be found. 746: * @throws ReflectionException if an exception was thrown in trying 747: * to invoke the bean's accessor. 748: * @throws RuntimeOperationsException if an {@link IllegalArgumentException} 749: * is thrown by the server due to a 750: * <code>null</code> bean or attribute 751: * name. 752: * @throws SecurityException if a security manager exists and the 753: * caller's permissions don't imply {@link 754: * MBeanPermission(String,String,ObjectName,String) 755: * <code>MBeanPermission(className, name, bean, 756: * "getAttribute")</code>}. 757: * @see DynamicMBean#getAttribute(String) 758: */ 759: public Object getAttribute(ObjectName bean, String name) 760: throws MBeanException, AttributeNotFoundException, 761: InstanceNotFoundException, ReflectionException 762: { 763: if (bean == null || name == null) 764: { 765: RuntimeException e = 766: new IllegalArgumentException("One of the supplied arguments was null."); 767: throw new RuntimeOperationsException(e); 768: } 769: Object abean = getBean(bean); 770: checkSecurity(bean, name, "getAttribute"); 771: if (abean instanceof DynamicMBean) 772: return ((DynamicMBean) abean).getAttribute(name); 773: else 774: try 775: { 776: return new StandardMBean(abean, null).getAttribute(name); 777: } 778: catch (NotCompliantMBeanException e) 779: { 780: throw (Error) 781: (new InternalError("Failed to create dynamic bean.").initCause(e)); 782: } 783: } 784: 785: 786: /** 787: * Returns the values of the named attributes from the specified 788: * management bean. 789: * 790: * @param bean the bean to retrieve the value from. 791: * @param names the names of the attributes to retrieve. 792: * @return the values of the attributes. 793: * @throws InstanceNotFoundException if the bean can not be found. 794: * @throws ReflectionException if an exception was thrown in trying 795: * to invoke the bean's accessor. 796: * @throws RuntimeOperationsException if an {@link IllegalArgumentException} 797: * is thrown by the server due to a 798: * <code>null</code> bean or attribute 799: * name. 800: * @throws SecurityException if a security manager exists and the 801: * caller's permissions don't imply {@link 802: * MBeanPermission(String,String,ObjectName,String) 803: * <code>MBeanPermission(className, null, bean, 804: * "getAttribute")</code>}. Additionally, 805: * for an attribute name, <code>n</code>, the 806: * caller's permission must imply {@link 807: * MBeanPermission(String,String,ObjectName,String) 808: * <code>MBeanPermission(className, n, bean, 809: * "getAttribute")</code>} or that attribute will 810: * not be included. 811: * 812: * @see DynamicMBean#getAttributes(String[]) 813: */ 814: public AttributeList getAttributes(ObjectName bean, String[] names) 815: throws InstanceNotFoundException, ReflectionException 816: { 817: if (bean == null || names == null) 818: { 819: RuntimeException e = 820: new IllegalArgumentException("One of the supplied arguments was null."); 821: throw new RuntimeOperationsException(e); 822: } 823: Object abean = getBean(bean); 824: checkSecurity(bean, null, "getAttribute"); 825: AttributeList list = new AttributeList(names.length); 826: for (int a = 0; a < names.length; ++a) 827: { 828: if (names[a] == null) 829: { 830: RuntimeException e = 831: new IllegalArgumentException("Argument " + a + " was null."); 832: throw new RuntimeOperationsException(e); 833: } 834: checkSecurity(bean, names[a], "getAttribute"); 835: try 836: { 837: Object value; 838: if (abean instanceof DynamicMBean) 839: value = ((DynamicMBean) abean).getAttribute(names[a]); 840: else 841: try 842: { 843: value = new StandardMBean(abean, null).getAttribute(names[a]); 844: } 845: catch (NotCompliantMBeanException e) 846: { 847: throw (Error) 848: (new InternalError("Failed to create dynamic bean.").initCause(e)); 849: } 850: list.add(new Attribute(names[a], value)); 851: } 852: catch (AttributeNotFoundException e) 853: { 854: /* Ignored */ 855: } 856: catch (MBeanException e) 857: { 858: /* Ignored */ 859: } 860: } 861: return list; 862: } 863: 864: 865: /** 866: * Returns the specified class loader. If the specified value is 867: * <code>null</code>, then the class loader of the server will be 868: * returned. If <code>l</code> is the requested class loader, 869: * and <code>r</code> is the actual class loader returned, then 870: * either <code>l</code> and <code>r</code> will be identical, 871: * or they will at least return the same class from 872: * {@link ClassLoader#loadClass(String)} for any given string. 873: * They may not be identical due to one or the other 874: * being wrapped in another class loader (e.g. for security). 875: * 876: * @param name the name of the class loader to return. 877: * @return the class loader. 878: * @throws InstanceNotFoundException if the class loader can not 879: * be found. 880: * @throws SecurityException if a security manager exists and the 881: * caller's permissions don't imply {@link 882: * MBeanPermission(String,String,ObjectName,String) 883: * <code>MBeanPermission(className, null, name, 884: * "getClassLoader")</code> 885: */ 886: public ClassLoader getClassLoader(ObjectName name) 887: throws InstanceNotFoundException 888: { 889: if (name == null) 890: { 891: checkSecurity(null, null, "getClassLoader"); 892: return getClass().getClassLoader(); 893: } 894: Object bean = getBean(name); 895: checkSecurity(name, null, "getClassLoader"); 896: return (ClassLoader) bean; 897: } 898: 899: /** 900: * Returns the class loader of the specified management bean. If 901: * <code>l</code> is the requested class loader, and <code>r</code> 902: * is the actual class loader returned, then either <code>l</code> 903: * and <code>r</code> will be identical, or they will at least 904: * return the same class from {@link ClassLoader#loadClass(String)} 905: * for any given string. They may not be identical due to one or 906: * the other being wrapped in another class loader (e.g. for 907: * security). 908: * 909: * @param name the name of the bean whose class loader should be 910: * returned. 911: * @return the class loader. 912: * @throws InstanceNotFoundException if the bean is not registered 913: * with the server. 914: * @throws SecurityException if a security manager exists and the 915: * caller's permissions don't imply {@link 916: * MBeanPermission(String,String,ObjectName,String) 917: * <code>MBeanPermission(className, null, name, 918: * "getClassLoaderFor")</code> 919: */ 920: public ClassLoader getClassLoaderFor(ObjectName name) 921: throws InstanceNotFoundException 922: { 923: Object bean = getBean(name); 924: checkSecurity(name, null, "getClassLoaderFor"); 925: return bean.getClass().getClassLoader(); 926: } 927: 928: /** 929: * Returns the class loader repository used by this server. 930: * 931: * @return the class loader repository. 932: * @throws SecurityException if a security manager exists and the 933: * caller's permissions don't imply {@link 934: * MBeanPermission(String,String,ObjectName,String) 935: * <code>MBeanPermission(null, null, null, 936: * "getClassLoaderRepository")</code> 937: */ 938: public ClassLoaderRepository getClassLoaderRepository() 939: { 940: return repository; 941: } 942: 943: /** 944: * Returns the default domain this server applies to beans that have 945: * no specified domain. 946: * 947: * @return the default domain. 948: */ 949: public String getDefaultDomain() 950: { 951: return defaultDomain; 952: } 953: 954: 955: /** 956: * Returns an array containing all the domains used by beans registered 957: * with this server. The ordering of the array is undefined. 958: * 959: * @return the list of domains. 960: * @throws SecurityException if a security manager exists and the 961: * caller's permissions don't imply {@link 962: * MBeanPermission(String,String,ObjectName,String) 963: * <code>MBeanPermission(null, null, name, 964: * "getDomains")</code>}. Additionally, 965: * for an domain, <code>d</code>, the 966: * caller's permission must imply {@link 967: * MBeanPermission(String,String,ObjectName,String) 968: * <code>MBeanPermission(null, null, 969: * new ObjectName("d:x=x"), "getDomains")</code>} 970: * or that domain will not be included. Note 971: * that "x=x" is an arbitrary key-value pair 972: * provided to satisfy the constructor. 973: * @see ObjectName#getDomain() 974: */ 975: public String[] getDomains() 976: { 977: checkSecurity(null, null, "getDomains"); 978: Set domains = new HashSet(); 979: Iterator iterator = beans.keySet().iterator(); 980: while (iterator.hasNext()) 981: { 982: String d = ((ObjectName) iterator.next()).getDomain(); 983: try 984: { 985: checkSecurity(new ObjectName(d + ":x=x"), null, "getDomains"); 986: domains.add(d); 987: } 988: catch (MalformedObjectNameException e) 989: { 990: /* Ignored */ 991: } 992: } 993: return (String[]) domains.toArray(new String[domains.size()]); 994: } 995: 996: /** 997: * Returns the number of management beans registered with this server. 998: * This may be less than the real number if the caller's access is 999: * restricted. 1000: * 1001: * @return the number of registered beans. 1002: */ 1003: public Integer getMBeanCount() 1004: { 1005: return Integer.valueOf(beans.size()); 1006: } 1007: 1008: /** 1009: * Returns information on the given management bean. 1010: * 1011: * @param name the name of the management bean. 1012: * @return an instance of {@link MBeanInfo} for the bean. 1013: * @throws IntrospectionException if an exception occurs in examining 1014: * the bean. 1015: * @throws InstanceNotFoundException if the bean can not be found. 1016: * @throws ReflectionException if an exception occurs when trying 1017: * to invoke {@link DynamicMBean#getMBeanInfo()} 1018: * on the bean. 1019: * @throws SecurityException if a security manager exists and the 1020: * caller's permissions don't imply {@link 1021: * MBeanPermission(String,String,ObjectName,String) 1022: * <code>MBeanPermission(className, null, name, 1023: * "getMBeanInfo")</code>}. 1024: * @see DynamicMBean#getMBeanInfo() 1025: */ 1026: public MBeanInfo getMBeanInfo(ObjectName name) 1027: throws InstanceNotFoundException, IntrospectionException, 1028: ReflectionException 1029: { 1030: Object bean = getBean(name); 1031: checkSecurity(name, null, "getMBeanInfo"); 1032: try 1033: { 1034: Method method = bean.getClass().getMethod("getMBeanInfo", null); 1035: return (MBeanInfo) method.invoke(bean, null); 1036: } 1037: catch (NoSuchMethodException e) 1038: { 1039: throw new IntrospectionException("The getMBeanInfo method " + 1040: "could not be found."); 1041: } 1042: catch (IllegalAccessException e) 1043: { 1044: throw new ReflectionException(e, "Failed to call getMBeanInfo"); 1045: } 1046: catch (IllegalArgumentException e) 1047: { 1048: throw new ReflectionException(e, "Failed to call getMBeanInfo"); 1049: } 1050: catch (InvocationTargetException e) 1051: { 1052: throw new ReflectionException(e, "The method threw an exception"); 1053: } 1054: } 1055: 1056: /** 1057: * Returns the {@link ObjectInstance} created for the specified 1058: * management bean on registration. 1059: * 1060: * @param name the name of the bean. 1061: * @return the corresponding {@link ObjectInstance} instance. 1062: * @throws InstanceNotFoundException if the bean can not be found. 1063: * @throws SecurityException if a security manager exists and the 1064: * caller's permissions don't imply {@link 1065: * MBeanPermission(String,String,ObjectName,String) 1066: * <code>MBeanPermission(className, null, name, 1067: * "getObjectInstance")</code> 1068: * @see #createMBean(String, ObjectName) 1069: */ 1070: public ObjectInstance getObjectInstance(ObjectName name) 1071: throws InstanceNotFoundException 1072: { 1073: ServerInfo bean = (ServerInfo) beans.get(name); 1074: if (bean == null) 1075: throw new InstanceNotFoundException("The bean, " + name + 1076: ", was not found."); 1077: return bean.getInstance(); 1078: } 1079: 1080: /** 1081: * <p> 1082: * Creates an instance of the specified class using the list of 1083: * class loaders from the {@link 1084: * javax.management.loading.ClassLoaderRepository Class Loader 1085: * Repository}. The class should have a public constructor 1086: * with no arguments. A reference to the new instance is returned, 1087: * but the instance is not yet registered with the server. 1088: * </p> 1089: * <p> 1090: * This method is equivalent to calling {@link 1091: * #instantiate(String, Object[], String[]) 1092: * <code>instantiate(name, (Object[]) null, (String[]) null)</code>} 1093: * with <code>null</code> parameters and signature. 1094: * </p> 1095: * 1096: * @param name the name of the class of bean to be instantiated. 1097: * @return an instance of the given class. 1098: * @throws ReflectionException if an exception is thrown during 1099: * loading the class or calling the 1100: * constructor. 1101: * @throws MBeanException if the constructor throws an exception. 1102: * @throws RuntimeOperationsException if an {@link IllegalArgumentException} 1103: * is thrown by the server due to a 1104: * <code>null</code> name. 1105: * @throws SecurityException if a security manager exists and the 1106: * caller's permissions don't imply {@link 1107: * MBeanPermission(String,String,ObjectName,String) 1108: * <code>MBeanPermission(className, null, null, 1109: * "instantiate")</code>}. 1110: * @see #instantiate(String, Object[], String[]) 1111: */ 1112: public Object instantiate(String name) 1113: throws ReflectionException, MBeanException 1114: { 1115: return instantiate(name, (Object[]) null, (String[]) null); 1116: } 1117: 1118: /** 1119: * Creates an instance of the specified class using the list of 1120: * class loaders from the {@link 1121: * javax.management.loading.ClassLoaderRepository Class Loader 1122: * Repository}. The class should have a public constructor 1123: * matching the supplied signature. A reference to the new 1124: * instance is returned, but the instance is not yet 1125: * registered with the server. 1126: * 1127: * @param name the name of the class of bean to be instantiated. 1128: * @param params the parameters for the constructor. 1129: * @param sig the signature of the constructor. 1130: * @return an instance of the given class. 1131: * @throws ReflectionException if an exception is thrown during 1132: * loading the class or calling the 1133: * constructor. 1134: * @throws MBeanException if the constructor throws an exception. 1135: * @throws RuntimeOperationsException if an {@link IllegalArgumentException} 1136: * is thrown by the server due to a 1137: * <code>null</code> name. 1138: * @throws SecurityException if a security manager exists and the 1139: * caller's permissions don't imply {@link 1140: * MBeanPermission(String,String,ObjectName,String) 1141: * <code>MBeanPermission(className, null, null, 1142: * "instantiate")</code>}. 1143: */ 1144: public Object instantiate(String name, Object[] params, String[] sig) 1145: throws ReflectionException, MBeanException 1146: { 1147: checkSecurity(null, null, "instantiate"); 1148: if (name == null) 1149: { 1150: RuntimeException e = 1151: new IllegalArgumentException("The name was null."); 1152: throw new RuntimeOperationsException(e); 1153: } 1154: Class[] sigTypes = new Class[sig.length]; 1155: for (int a = 0; a < sigTypes.length; ++a) 1156: { 1157: try 1158: { 1159: sigTypes[a] = repository.loadClass(sig[a]); 1160: } 1161: catch (ClassNotFoundException e) 1162: { 1163: throw new ReflectionException(e, "The class, " + sigTypes[a] + 1164: ", in the method signature " + 1165: "could not be loaded."); 1166: } 1167: } 1168: try 1169: { 1170: Constructor cons = 1171: repository.loadClass(name).getConstructor(sigTypes); 1172: return cons.newInstance(params); 1173: } 1174: catch (ClassNotFoundException e) 1175: { 1176: throw new ReflectionException(e, "The class, " + name + 1177: ", of the constructor " + 1178: "could not be loaded."); 1179: } 1180: catch (NoSuchMethodException e) 1181: { 1182: throw new ReflectionException(e, "The method, " + name + 1183: ", could not be found."); 1184: } 1185: catch (IllegalAccessException e) 1186: { 1187: throw new ReflectionException(e, "Failed to instantiate the object"); 1188: } 1189: catch (InstantiationException e) 1190: { 1191: throw new ReflectionException(e, "Failed to instantiate the object"); 1192: } 1193: catch (InvocationTargetException e) 1194: { 1195: throw new MBeanException((Exception) e.getCause(), "The constructor " 1196: + name + " threw an exception"); 1197: } 1198: } 1199: 1200: /** 1201: * <p> 1202: * Creates an instance of the specified class using the supplied 1203: * class loader. If the class loader given is <code>null</code>, 1204: * then the class loader of the server will be used. The class 1205: * should have a public constructor with no arguments. A reference 1206: * to the new instance is returned, but the instance is not yet 1207: * registered with the server. 1208: * </p> 1209: * <p> 1210: * This method is equivalent to calling {@link 1211: * #instantiate(String, ObjectName, Object[], String[]) 1212: * <code>instantiate(name, loaderName, (Object[]) null, 1213: * (String[]) null)</code>} with <code>null</code> parameters 1214: * and signature. 1215: * </p> 1216: * 1217: * @param name the name of the class of bean to be instantiated. 1218: * @param loaderName the name of the class loader to use. 1219: * @return an instance of the given class. 1220: * @throws InstanceNotFoundException if the class loader is not 1221: * registered with the server. 1222: * @throws ReflectionException if an exception is thrown during 1223: * loading the class or calling the 1224: * constructor. 1225: * @throws MBeanException if the constructor throws an exception. 1226: * @throws RuntimeOperationsException if an {@link IllegalArgumentException} 1227: * is thrown by the server due to a 1228: * <code>null</code> name. 1229: * @throws SecurityException if a security manager exists and the 1230: * caller's permissions don't imply {@link 1231: * MBeanPermission(String,String,ObjectName,String) 1232: * <code>MBeanPermission(className, null, null, 1233: * "instantiate")</code>}. 1234: * @see #instantiate(String, Object[], String[]) 1235: */ 1236: public Object instantiate(String name, ObjectName loaderName) 1237: throws InstanceNotFoundException, ReflectionException, 1238: MBeanException 1239: { 1240: return instantiate(name, loaderName); 1241: } 1242: 1243: /** 1244: * Creates an instance of the specified class using the supplied 1245: * class loader. If the class loader given is <code>null</code>, 1246: * then the class loader of the server will be used. The class 1247: * should have a public constructor matching the supplied 1248: * signature. A reference to the new instance is returned, 1249: * but the instance is not yet registered with the server. 1250: * 1251: * @param name the name of the class of bean to be instantiated. 1252: * @param loaderName the name of the class loader to use. 1253: * @param params the parameters for the constructor. 1254: * @param sig the signature of the constructor. 1255: * @return an instance of the given class. 1256: * @throws InstanceNotFoundException if the class loader is not 1257: * registered with the server. 1258: * @throws ReflectionException if an exception is thrown during 1259: * loading the class or calling the 1260: * constructor. 1261: * @throws MBeanException if the constructor throws an exception. 1262: * @throws RuntimeOperationsException if an {@link IllegalArgumentException} 1263: * is thrown by the server due to a 1264: * <code>null</code> name. 1265: * @throws SecurityException if a security manager exists and the 1266: * caller's permissions don't imply {@link 1267: * MBeanPermission(String,String,ObjectName,String) 1268: * <code>MBeanPermission(className, null, null, 1269: * "instantiate")</code>}. 1270: */ 1271: public Object instantiate(String name, ObjectName loaderName, 1272: Object[] params, String[] sig) 1273: throws InstanceNotFoundException, ReflectionException, 1274: MBeanException 1275: { 1276: checkSecurity(null, null, "instantiate"); 1277: if (name == null) 1278: { 1279: RuntimeException e = 1280: new IllegalArgumentException("The name was null."); 1281: throw new RuntimeOperationsException(e); 1282: } 1283: ClassLoader loader = getClassLoader(loaderName); 1284: Class[] sigTypes = new Class[sig.length]; 1285: for (int a = 0; a < sig.length; ++a) 1286: { 1287: try 1288: { 1289: sigTypes[a] = Class.forName(sig[a], true, loader); 1290: } 1291: catch (ClassNotFoundException e) 1292: { 1293: throw new ReflectionException(e, "The class, " + sig[a] + 1294: ", in the method signature " + 1295: "could not be loaded."); 1296: } 1297: } 1298: try 1299: { 1300: Constructor cons = 1301: Class.forName(name, true, loader).getConstructor(sigTypes); 1302: return cons.newInstance(params); 1303: } 1304: catch (ClassNotFoundException e) 1305: { 1306: throw new ReflectionException(e, "The class, " + name + 1307: ", of the constructor " + 1308: "could not be loaded."); 1309: } 1310: catch (NoSuchMethodException e) 1311: { 1312: throw new ReflectionException(e, "The method, " + name + 1313: ", could not be found."); 1314: } 1315: catch (IllegalAccessException e) 1316: { 1317: throw new ReflectionException(e, "Failed to instantiate the object"); 1318: } 1319: catch (InstantiationException e) 1320: { 1321: throw new ReflectionException(e, "Failed to instantiate the object"); 1322: } 1323: catch (InvocationTargetException e) 1324: { 1325: throw new MBeanException((Exception) e.getCause(), "The constructor " 1326: + name + " threw an exception"); 1327: } 1328: } 1329: 1330: /** 1331: * Invokes the supplied operation on the specified management 1332: * bean. The class objects specified in the signature are loaded 1333: * using the same class loader as was used for the management bean. 1334: * 1335: * @param bean the management bean whose operation should be invoked. 1336: * @param name the name of the operation to invoke. 1337: * @param params the parameters of the operation. 1338: * @param sig the signature of the operation. 1339: * @return the return value of the method. 1340: * @throws InstanceNotFoundException if the bean can not be found. 1341: * @throws MBeanException if the method invoked throws an exception. 1342: * @throws RuntimeOperationsException if an {@link IllegalArgumentException} 1343: * is thrown by the server due to a 1344: * <code>null</code> name. 1345: * @throws ReflectionException if an exception is thrown in invoking the 1346: * method. 1347: * @throws SecurityException if a security manager exists and the 1348: * caller's permissions don't imply {@link 1349: * MBeanPermission(String,String,ObjectName,String) 1350: * <code>MBeanPermission(className, name, bean, 1351: * "invoke")</code>}. 1352: * @see DynamicMBean#invoke(String, Object[], String[]) 1353: */ 1354: public Object invoke(ObjectName bean, String name, Object[] params, String[] sig) 1355: throws InstanceNotFoundException, MBeanException, 1356: ReflectionException 1357: { 1358: if (bean == null) 1359: { 1360: RuntimeException e = 1361: new IllegalArgumentException("The bean was null."); 1362: throw new RuntimeOperationsException(e); 1363: } 1364: Object abean = getBean(bean); 1365: checkSecurity(bean, name, "invoke"); 1366: if (abean instanceof DynamicMBean) 1367: return ((DynamicMBean) abean).invoke(name, params, sig); 1368: else 1369: try 1370: { 1371: return new StandardMBean(abean, null).invoke(name, params, sig); 1372: } 1373: catch (NotCompliantMBeanException e) 1374: { 1375: throw (Error) 1376: (new InternalError("Failed to create dynamic bean.").initCause(e)); 1377: } 1378: } 1379: 1380: /** 1381: * <p> 1382: * Returns true if the specified management bean is an instance 1383: * of the supplied class. 1384: * </p> 1385: * <p> 1386: * A bean, B, is an instance of a class, C, if either of the following 1387: * conditions holds: 1388: * </p> 1389: * <ul> 1390: * <li>The class name in B's {@link MBeanInfo} is equal to the supplied 1391: * name.</li> 1392: * <li>Both the class of B and C were loaded by the same class loader, 1393: * and B is assignable to C.</li> 1394: * </ul> 1395: * 1396: * @param name the name of the management bean. 1397: * @param className the name of the class to test if <code>name</code> is 1398: * an instance of. 1399: * @return true if either B is directly an instance of the named class, 1400: * or B is assignable to the class, given that both it and B's 1401: * current class were loaded using the same class loader. 1402: * @throws InstanceNotFoundException if the bean can not be found. 1403: * @throws SecurityException if a security manager exists and the 1404: * caller's permissions don't imply {@link 1405: * MBeanPermission(String,String,ObjectName,String) 1406: * <code>MBeanPermission(className, null, name, 1407: * "isInstanceOf")</code> 1408: */ 1409: public boolean isInstanceOf(ObjectName name, String className) 1410: throws InstanceNotFoundException 1411: { 1412: Object bean = getBean(name); 1413: checkSecurity(name, null, "isInstanceOf"); 1414: MBeanInfo info; 1415: if (bean instanceof DynamicMBean) 1416: info = ((DynamicMBean) bean).getMBeanInfo(); 1417: else 1418: try 1419: { 1420: info = new StandardMBean(bean, null).getMBeanInfo(); 1421: } 1422: catch (NotCompliantMBeanException e) 1423: { 1424: throw (Error) 1425: (new InternalError("Failed to create dynamic bean.").initCause(e)); 1426: } 1427: if (info.getClassName().equals(className)) 1428: return true; 1429: Class bclass = bean.getClass(); 1430: try 1431: { 1432: Class oclass = Class.forName(className); 1433: return (bclass.getClassLoader().equals(oclass.getClassLoader()) && 1434: oclass.isAssignableFrom(bclass)); 1435: } 1436: catch (ClassNotFoundException e) 1437: { 1438: return false; 1439: } 1440: } 1441: 1442: /** 1443: * Returns true if the specified management bean is registered with 1444: * the server. 1445: * 1446: * @param name the name of the management bean. 1447: * @return true if the bean is registered. 1448: * @throws RuntimeOperationsException if an {@link IllegalArgumentException} 1449: * is thrown by the server due to a 1450: * <code>null</code> bean name. 1451: */ 1452: public boolean isRegistered(ObjectName name) 1453: { 1454: if (name == null) 1455: { 1456: RuntimeException e = 1457: new IllegalArgumentException("The name was null."); 1458: throw new RuntimeOperationsException(e); 1459: } 1460: return beans.containsKey(name); 1461: } 1462: 1463: /** 1464: * <p> 1465: * Returns a set of {@link ObjectInstance}s matching the specified 1466: * criteria. The full set of beans registered with the server 1467: * are passed through two filters: 1468: * </p> 1469: * <ol> 1470: * <li>Pattern matching is performed using the supplied 1471: * {@link ObjectName}.</li> 1472: * <li>The supplied query expression is applied.</li> 1473: * </ol> 1474: * <p> 1475: * If both the object name and the query expression are <code>null</code>, 1476: * or the object name has no domain and no key properties, 1477: * no filtering will be performed and all beans are returned. 1478: * </p> 1479: * 1480: * @param name an {@link ObjectName} to use as a filter. 1481: * @param query a query expression to apply to each of the beans that match 1482: * the given object name. 1483: * @return a set of {@link ObjectInstance}s matching the filtered beans. 1484: * @throws SecurityException if a security manager exists and the 1485: * caller's permissions don't imply {@link 1486: * MBeanPermission(String,String,ObjectName,String) 1487: * <code>MBeanPermission(null, null, name, 1488: * "queryMBeans")</code>}. Additionally, 1489: * for an bean, <code>b</code>, the 1490: * caller's permission must imply {@link 1491: * MBeanPermission(String,String,ObjectName,String) 1492: * <code>MBeanPermission(className, b, name, 1493: * "queryMBeans")</code>} or that bean will 1494: * not be included. Such an exception may also 1495: * arise from the execution of the query, in which 1496: * case that particular bean will again be excluded. 1497: */ 1498: public Set queryMBeans(ObjectName name, QueryExp query) 1499: { 1500: checkSecurity(name, null, "queryMBeans"); 1501: Set results = new HashSet(); 1502: Iterator iterator = beans.entrySet().iterator(); 1503: while (iterator.hasNext()) 1504: { 1505: Map.Entry entry = (Map.Entry) iterator.next(); 1506: ObjectName nextName = (ObjectName) entry.getKey(); 1507: checkSecurity(name, nextName.toString(), "queryMBeans"); 1508: try 1509: { 1510: if ((name == null || name.apply(nextName)) && 1511: (query == null || query.apply(nextName))) 1512: results.add(((ServerInfo) entry.getValue()).getInstance()); 1513: } 1514: catch (BadStringOperationException e) 1515: { 1516: /* Ignored -- assume false result */ 1517: } 1518: catch (BadBinaryOpValueExpException e) 1519: { 1520: /* Ignored -- assume false result */ 1521: } 1522: catch (BadAttributeValueExpException e) 1523: { 1524: /* Ignored -- assume false result */ 1525: } 1526: catch (InvalidApplicationException e) 1527: { 1528: /* Ignored -- assume false result */ 1529: } 1530: } 1531: return results; 1532: } 1533: 1534: /** 1535: * <p> 1536: * Returns a set of {@link ObjectName}s matching the specified 1537: * criteria. The full set of beans registered with the server 1538: * are passed through two filters: 1539: * </p> 1540: * <ol> 1541: * <li>Pattern matching is performed using the supplied 1542: * {@link ObjectName}.</li> 1543: * <li>The supplied query expression is applied.</li> 1544: * </ol> 1545: * <p> 1546: * If both the object name and the query expression are <code>null</code>, 1547: * or the object name has no domain and no key properties, 1548: * no filtering will be performed and all beans are returned. 1549: * </p> 1550: * 1551: * @param name an {@link ObjectName} to use as a filter. 1552: * @param query a query expression to apply to each of the beans that match 1553: * the given object name. 1554: * @return a set of {@link ObjectName}s matching the filtered beans. 1555: * @throws SecurityException if a security manager exists and the 1556: * caller's permissions don't imply {@link 1557: * MBeanPermission(String,String,ObjectName,String) 1558: * <code>MBeanPermission(null, null, name, 1559: * "queryNames")</code>}. Additionally, 1560: * for an name, <code>n</code>, the 1561: * caller's permission must imply {@link 1562: * MBeanPermission(String,String,ObjectName,String) 1563: * <code>MBeanPermission(className, n, name, 1564: * "queryNames")</code>} or that name will 1565: * not be included. Such an exception may also 1566: * arise from the execution of the query, in which 1567: * case that particular bean will again be excluded. 1568: * Note that these permissions are implied if the 1569: * <code>queryMBeans</code> permissions are available. 1570: */ 1571: public Set queryNames(ObjectName name, QueryExp query) 1572: { 1573: checkSecurity(name, null, "queryNames"); 1574: Set results = new HashSet(); 1575: Iterator iterator = beans.entrySet().iterator(); 1576: while (iterator.hasNext()) 1577: { 1578: Map.Entry entry = (Map.Entry) iterator.next(); 1579: ObjectName nextName = (ObjectName) entry.getKey(); 1580: checkSecurity(name, nextName.toString(), "queryNames"); 1581: try 1582: { 1583: if ((name == null || name.apply(nextName)) && 1584: (query == null || query.apply(nextName))) 1585: results.add(nextName); 1586: } 1587: catch (BadStringOperationException e) 1588: { 1589: /* Ignored -- assume false result */ 1590: } 1591: catch (BadBinaryOpValueExpException e) 1592: { 1593: /* Ignored -- assume false result */ 1594: } 1595: catch (BadAttributeValueExpException e) 1596: { 1597: /* Ignored -- assume false result */ 1598: } 1599: catch (InvalidApplicationException e) 1600: { 1601: /* Ignored -- assume false result */ 1602: } 1603: } 1604: return results; 1605: } 1606: 1607: /** 1608: * Registers the supplied instance with the server, using the specified 1609: * {@link ObjectName}. If the name given is <code>null</code>, then 1610: * the bean supplied is expected to implement the {@link MBeanRegistration} 1611: * interface and provide the name via the 1612: * {@link MBeanRegistration#preRegister preRegister} method 1613: * of this interface. 1614: * 1615: * @param obj the object to register with the server. 1616: * @param name the name under which to register the object, 1617: * or <code>null</code> if the {@link MBeanRegistration} 1618: * interface should be used. 1619: * @return an {@link ObjectInstance} containing the supplied 1620: * {@link ObjectName} along with the name of the bean's class. 1621: * @throws InstanceAlreadyExistsException if a matching instance 1622: * already exists. 1623: * @throws MBeanRegistrationException if an exception occurs in 1624: * calling the preRegister 1625: * method. 1626: * @throws NotCompliantMBeanException if the created bean is not 1627: * compliant with the JMX specification. 1628: * @throws RuntimeOperationsException if an {@link IllegalArgumentException} 1629: * is thrown by the server due to a 1630: * <code>null</code> object. 1631: * @throws SecurityException if a security manager exists and the 1632: * caller's permissions don't imply {@link 1633: * MBeanPermission(String,String,ObjectName,String) 1634: * <code>MBeanPermission(className, null, name, 1635: * "registerMBean")</code>}. <code>className</code> 1636: * here corresponds to the result of 1637: * {@link MBeanInfo#getClassName()} for objects of 1638: * this class. If this check succeeds, a check 1639: * is also made on its 1640: * {@link java.security.ProtectionDomain} to ensure 1641: * it implies {@link MBeanTrustPermission(String) 1642: * <code>MBeanTrustPermission("register")</code>}. 1643: * The use of the {@link MBeanRegistration} interface 1644: * results in another {@link MBeanPermission} check 1645: * being made on the returned {@link ObjectName}. 1646: */ 1647: public ObjectInstance registerMBean(Object obj, ObjectName name) 1648: throws InstanceAlreadyExistsException, MBeanRegistrationException, 1649: NotCompliantMBeanException 1650: { 1651: SecurityManager sm = System.getSecurityManager(); 1652: Class cl = obj.getClass(); 1653: String className = cl.getName(); 1654: if (sm != null) 1655: { 1656: sm.checkPermission(new MBeanPermission(className, null, name, 1657: "registerMBean")); 1658: if (!(cl.getProtectionDomain().implies(new MBeanTrustPermission("register")))) 1659: throw new SecurityException("The protection domain of the object's class" + 1660: "does not imply the trust permission," + 1661: "register"); 1662: } 1663: if (obj == null) 1664: { 1665: RuntimeException e = 1666: new IllegalArgumentException("The object was null."); 1667: throw new RuntimeOperationsException(e); 1668: } 1669: MBeanRegistration register = null; 1670: if (obj instanceof MBeanRegistration) 1671: register = (MBeanRegistration) obj; 1672: if (name == null && register == null) 1673: { 1674: RuntimeException e = 1675: new IllegalArgumentException("The name was null and " + 1676: "the bean does not implement " + 1677: "MBeanRegistration."); 1678: throw new RuntimeOperationsException(e); 1679: } 1680: if (register != null) 1681: { 1682: try 1683: { 1684: name = register.preRegister(this, name); 1685: if (name == null) 1686: { 1687: RuntimeException e = 1688: new NullPointerException("The name returned by " + 1689: "MBeanRegistration.preRegister() " + 1690: "was null"); 1691: throw e; 1692: } 1693: if (sm != null) 1694: sm.checkPermission(new MBeanPermission(className, null, name, 1695: "registerMBean")); 1696: } 1697: catch (SecurityException e) 1698: { 1699: register.postRegister(Boolean.FALSE); 1700: throw e; 1701: } 1702: catch (Exception e) 1703: { 1704: register.postRegister(Boolean.FALSE); 1705: throw new MBeanRegistrationException(e, "Pre-registration failed."); 1706: } 1707: } 1708: if (beans.containsKey(name)) 1709: { 1710: if (register != null) 1711: register.postRegister(Boolean.FALSE); 1712: throw new InstanceAlreadyExistsException(name + "is already registered."); 1713: } 1714: ObjectInstance obji = new ObjectInstance(name, className); 1715: beans.put(name, new ServerInfo(obji, obj)); 1716: if (register != null) 1717: register.postRegister(Boolean.TRUE); 1718: notify(name, MBeanServerNotification.REGISTRATION_NOTIFICATION); 1719: return obji; 1720: } 1721: 1722: /** 1723: * Removes the specified listener from the list of recipients 1724: * of notifications from the supplied bean. This includes all 1725: * combinations of filters and passback objects registered for 1726: * this listener. For more specific removal of listeners, see 1727: * {@link #removeNotificationListener(ObjectName, 1728: * NotificationListener,NotificationFilter,Object)} 1729: * 1730: * @param name the name of the management bean from which the 1731: * listener should be removed. 1732: * @param listener the listener to remove. 1733: * @throws InstanceNotFoundException if the bean can not be found. 1734: * @throws ListenerNotFoundException if the specified listener 1735: * is not registered with the bean. 1736: * @throws SecurityException if a security manager exists and the 1737: * caller's permissions don't imply {@link 1738: * MBeanPermission(String,String,ObjectName,String) 1739: * <code>MBeanPermission(className, null, name, 1740: * "removeNotificationListener")</code>}. 1741: * @see #addNotificationListener(NotificationListener, NotificationFilter, 1742: * java.lang.Object) 1743: * @see NotificationBroadcaster#removeNotificationListener(NotificationListener) 1744: */ 1745: public void removeNotificationListener(ObjectName name, 1746: NotificationListener listener) 1747: throws InstanceNotFoundException, ListenerNotFoundException 1748: { 1749: Object bean = getBean(name); 1750: checkSecurity(name, null, "removeNotificationListener"); 1751: if (bean instanceof NotificationBroadcaster) 1752: { 1753: NotificationBroadcaster bbean = (NotificationBroadcaster) bean; 1754: NotificationListener indirection = (NotificationListener) 1755: listeners.get(listener); 1756: if (indirection == null) 1757: bbean.removeNotificationListener(listener); 1758: else 1759: { 1760: bbean.removeNotificationListener(indirection); 1761: listeners.remove(listener); 1762: } 1763: } 1764: } 1765: 1766: /** 1767: * Removes the specified listener from the list of recipients 1768: * of notifications from the supplied bean. Only the first instance with 1769: * the supplied filter and passback object is removed. 1770: * <code>null</code> is used as a valid value for these parameters, 1771: * rather than as a way to remove all registration instances for 1772: * the specified listener; for this behaviour instead, see 1773: * {@link #removeNotificationListener(ObjectName, NotificationListener)}. 1774: * 1775: * @param name the name of the management bean from which the 1776: * listener should be removed. 1777: * @param listener the listener to remove. 1778: * @param filter the filter of the listener to remove. 1779: * @param passback the passback object of the listener to remove. 1780: * @throws InstanceNotFoundException if the bean can not be found. 1781: * @throws ListenerNotFoundException if the specified listener 1782: * is not registered with the bean. 1783: * @throws SecurityException if a security manager exists and the 1784: * caller's permissions don't imply {@link 1785: * MBeanPermission(String,String,ObjectName,String) 1786: * <code>MBeanPermission(className, null, name, 1787: * "removeNotificationListener")</code>}. 1788: * @see #addNotificationListener(ObjectName, NotificationListener, 1789: * NotificationFilter, Object) 1790: * @see NotificationEmitter#removeNotificationListener(NotificationListener, 1791: * NotificationFilter, 1792: * Object) 1793: */ 1794: public void removeNotificationListener(ObjectName name, 1795: NotificationListener listener, 1796: NotificationFilter filter, 1797: Object passback) 1798: throws InstanceNotFoundException, ListenerNotFoundException 1799: { 1800: Object bean = getBean(name); 1801: checkSecurity(name, null, "removeNotificationListener"); 1802: if (bean instanceof NotificationEmitter) 1803: { 1804: NotificationEmitter bbean = (NotificationEmitter) bean; 1805: NotificationListener indirection = (NotificationListener) 1806: listeners.get(listener); 1807: if (indirection == null) 1808: bbean.removeNotificationListener(listener, filter, passback); 1809: else 1810: { 1811: bbean.removeNotificationListener(indirection, filter, passback); 1812: listeners.remove(listener); 1813: } 1814: } 1815: } 1816: 1817: /** 1818: * Removes the specified listener from the list of recipients 1819: * of notifications from the supplied bean. This includes all 1820: * combinations of filters and passback objects registered for 1821: * this listener. For more specific removal of listeners, see 1822: * {@link #removeNotificationListener(ObjectName, 1823: * ObjectName,NotificationFilter,Object)} 1824: * 1825: * @param name the name of the management bean from which the 1826: * listener should be removed. 1827: * @param listener the name of the listener to remove. 1828: * @throws InstanceNotFoundException if a name doesn't match a registered 1829: * bean. 1830: * @throws ListenerNotFoundException if the specified listener 1831: * is not registered with the bean. 1832: * @throws SecurityException if a security manager exists and the 1833: * caller's permissions don't imply {@link 1834: * MBeanPermission(String,String,ObjectName,String) 1835: * <code>MBeanPermission(className, null, name, 1836: * "removeNotificationListener")</code>}. 1837: * @see #addNotificationListener(NotificationListener, NotificationFilter, 1838: * java.lang.Object) 1839: * @see NotificationBroadcaster#removeNotificationListener(NotificationListener) 1840: */ 1841: public void removeNotificationListener(ObjectName name, ObjectName listener) 1842: throws InstanceNotFoundException, ListenerNotFoundException 1843: { 1844: Object lbean = getBean(listener); 1845: if (!(lbean instanceof NotificationListener)) 1846: { 1847: RuntimeException e = 1848: new IllegalArgumentException("The supplied listener name does not " + 1849: "correspond to a notification listener."); 1850: throw new RuntimeOperationsException(e); 1851: } 1852: removeNotificationListener(name, ((NotificationListener) lbean)); 1853: } 1854: 1855: /** 1856: * Removes the specified listener from the list of recipients 1857: * of notifications from the supplied bean. Only the first instance with 1858: * the supplied filter and passback object is removed. 1859: * <code>null</code> is used as a valid value for these parameters, 1860: * rather than as a way to remove all registration instances for 1861: * the specified listener; for this behaviour instead, see 1862: * {@link #removeNotificationListener(ObjectName, ObjectName)}. 1863: * 1864: * @param name the name of the management bean from which the 1865: * listener should be removed. 1866: * @param listener the name of the listener to remove. 1867: * @param filter the filter of the listener to remove. 1868: * @param passback the passback object of the listener to remove. 1869: * @throws InstanceNotFoundException if a name doesn't match a registered 1870: * bean. 1871: * @throws ListenerNotFoundException if the specified listener 1872: * is not registered with the bean. 1873: * @throws SecurityException if a security manager exists and the 1874: * caller's permissions don't imply {@link 1875: * MBeanPermission(String,String,ObjectName,String) 1876: * <code>MBeanPermission(className, null, name, 1877: * "removeNotificationListener")</code>}. 1878: * @see #addNotificationListener(ObjectName, NotificationListener, 1879: * NotificationFilter, Object) 1880: * @see NotificationEmitter#removeNotificationListener(NotificationListener, 1881: * NotificationFilter, 1882: * Object) 1883: */ 1884: public void removeNotificationListener(ObjectName name, 1885: ObjectName listener, 1886: NotificationFilter filter, 1887: Object passback) 1888: throws InstanceNotFoundException, ListenerNotFoundException 1889: { 1890: Object lbean = getBean(listener); 1891: if (!(lbean instanceof NotificationListener)) 1892: { 1893: RuntimeException e = 1894: new IllegalArgumentException("The supplied listener name does not " + 1895: "correspond to a notification listener."); 1896: throw new RuntimeOperationsException(e); 1897: } 1898: removeNotificationListener(name, ((NotificationListener) lbean), filter, 1899: passback); 1900: } 1901: 1902: /** 1903: * Sets the value of the specified attribute of the supplied 1904: * management bean. 1905: * 1906: * @param name the name of the management bean. 1907: * @param attribute the attribute to set. 1908: * @throws InstanceNotFoundException if the bean can not be found. 1909: * @throws AttributeNotFoundException if the attribute does not 1910: * correspond to an attribute 1911: * of the bean. 1912: * @throws InvalidAttributeValueException if the value is invalid 1913: * for this particular 1914: * attribute of the bean. 1915: * @throws MBeanException if setting the attribute causes 1916: * the bean to throw an exception (which 1917: * becomes the cause of this exception). 1918: * @throws ReflectionException if an exception occurred in trying 1919: * to use the reflection interface 1920: * to lookup the attribute. The 1921: * thrown exception is the cause of 1922: * this exception. 1923: * @throws RuntimeOperationsException if an {@link IllegalArgumentException} 1924: * is thrown by the server due to a 1925: * <code>null</code> bean or attribute 1926: * name. 1927: * @throws SecurityException if a security manager exists and the 1928: * caller's permissions don't imply {@link 1929: * MBeanPermission(String,String,ObjectName,String) 1930: * <code>MBeanPermission(className, name, bean, 1931: * "setAttribute")</code>}. 1932: * @see #getAttribute(ObjectName, String) 1933: * @see DynamicMBean#setAttribute(Attribute) 1934: */ 1935: public void setAttribute(ObjectName name, Attribute attribute) 1936: throws InstanceNotFoundException, AttributeNotFoundException, 1937: InvalidAttributeValueException, MBeanException, 1938: ReflectionException 1939: { 1940: if (attribute == null || name == null) 1941: { 1942: RuntimeException e = 1943: new IllegalArgumentException("One of the supplied arguments was null."); 1944: throw new RuntimeOperationsException(e); 1945: } 1946: Object bean = getBean(name); 1947: checkSecurity(name, attribute.getName(), "setAttribute"); 1948: if (bean instanceof DynamicMBean) 1949: ((DynamicMBean) bean).setAttribute(attribute); 1950: else 1951: try 1952: { 1953: new StandardMBean(bean, null).setAttribute(attribute); 1954: } 1955: catch (NotCompliantMBeanException e) 1956: { 1957: throw (Error) 1958: (new InternalError("Failed to create dynamic bean.").initCause(e)); 1959: } 1960: } 1961: 1962: /** 1963: * Sets the value of each of the specified attributes 1964: * of the supplied management bean to that specified by 1965: * the {@link Attribute} object. The returned list contains 1966: * the attributes that were set and their new values. 1967: * 1968: * @param name the name of the management bean. 1969: * @param attributes the attributes to set. 1970: * @return a list of the changed attributes. 1971: * @throws InstanceNotFoundException if the bean can not be found. 1972: * @throws ReflectionException if an exception occurred in trying 1973: * to use the reflection interface 1974: * to lookup the attribute. The 1975: * thrown exception is the cause of 1976: * this exception. 1977: * @throws RuntimeOperationsException if an {@link IllegalArgumentException} 1978: * is thrown by the server due to a 1979: * <code>null</code> bean or attribute 1980: * list. 1981: * @throws SecurityException if a security manager exists and the 1982: * caller's permissions don't imply {@link 1983: * MBeanPermission(String,String,ObjectName,String) 1984: * <code>MBeanPermission(className, null, bean, 1985: * "setAttribute")</code>}. Additionally, 1986: * for an attribute name, <code>n</code>, the 1987: * caller's permission must imply {@link 1988: * MBeanPermission(String,String,ObjectName,String) 1989: * <code>MBeanPermission(className, n, bean, 1990: * "setAttribute")</code>} or that attribute will 1991: * not be included. 1992: * @see #getAttributes(ObjectName, String[]) 1993: * @see DynamicMBean#setAttributes(AttributeList) 1994: */ 1995: public AttributeList setAttributes(ObjectName name, AttributeList attributes) 1996: throws InstanceNotFoundException, ReflectionException 1997: { 1998: if (name == null || attributes == null) 1999: { 2000: RuntimeException e = 2001: new IllegalArgumentException("One of the supplied arguments was null."); 2002: throw new RuntimeOperationsException(e); 2003: } 2004: Object abean = getBean(name); 2005: checkSecurity(name, null, "setAttribute"); 2006: AttributeList list = new AttributeList(attributes.size()); 2007: Iterator it = attributes.iterator(); 2008: while (it.hasNext()) 2009: { 2010: try 2011: { 2012: Attribute attrib = (Attribute) it.next(); 2013: if (attrib == null) 2014: { 2015: RuntimeException e = 2016: new IllegalArgumentException("An attribute was null."); 2017: throw new RuntimeOperationsException(e); 2018: } 2019: checkSecurity(name, attrib.getName(), "setAttribute"); 2020: if (abean instanceof DynamicMBean) 2021: ((DynamicMBean) abean).setAttribute(attrib); 2022: else 2023: try 2024: { 2025: new StandardMBean(abean, null).setAttribute(attrib); 2026: } 2027: catch (NotCompliantMBeanException e) 2028: { 2029: throw (Error) 2030: (new InternalError("Failed to create dynamic bean.").initCause(e)); 2031: } 2032: list.add(attrib); 2033: } 2034: catch (AttributeNotFoundException e) 2035: { 2036: /* Ignored */ 2037: } 2038: catch (InvalidAttributeValueException e) 2039: { 2040: /* Ignored */ 2041: } 2042: catch (MBeanException e) 2043: { 2044: /* Ignored */ 2045: } 2046: } 2047: return list; 2048: } 2049: 2050: /** 2051: * Unregisters the specified management bean. Following this operation, 2052: * the bean instance is no longer accessible from the server via this 2053: * name. Prior to unregistering the bean, the 2054: * {@link MBeanRegistration#preDeregister()} method will be called if 2055: * the bean implements the {@link MBeanRegistration} interface. 2056: * 2057: * @param name the name of the management bean. 2058: * @throws InstanceNotFoundException if the bean can not be found. 2059: * @throws MBeanRegistrationException if an exception occurs in 2060: * calling the preDeregister 2061: * method. 2062: * @throws RuntimeOperationsException if an {@link IllegalArgumentException} 2063: * is thrown by the server due to a 2064: * <code>null</code> bean name or a 2065: * request being made to unregister the 2066: * {@link MBeanServerDelegate} bean. 2067: * @throws SecurityException if a security manager exists and the 2068: * caller's permissions don't imply {@link 2069: * MBeanPermission(String,String,ObjectName,String) 2070: * <code>MBeanPermission(className, null, name, 2071: * "unregisterMBean")</code>}. 2072: */ 2073: public void unregisterMBean(ObjectName name) 2074: throws InstanceNotFoundException, MBeanRegistrationException 2075: { 2076: if (name == null) 2077: { 2078: RuntimeException e = 2079: new IllegalArgumentException("The name was null."); 2080: throw new RuntimeOperationsException(e); 2081: } 2082: if (name.equals(DELEGATE_NAME)) 2083: { 2084: RuntimeException e = 2085: new IllegalArgumentException("The delegate can not be unregistered."); 2086: throw new RuntimeOperationsException(e); 2087: } 2088: Object bean = getBean(name); 2089: checkSecurity(name, null, "unregisterMBean"); 2090: MBeanRegistration register = null; 2091: if (bean instanceof MBeanRegistration) 2092: { 2093: register = (MBeanRegistration) bean; 2094: try 2095: { 2096: register.preDeregister(); 2097: } 2098: catch (Exception e) 2099: { 2100: throw new MBeanRegistrationException(e, "Pre-deregistration failed."); 2101: } 2102: } 2103: beans.remove(name); 2104: notify(name, MBeanServerNotification.UNREGISTRATION_NOTIFICATION); 2105: if (register != null) 2106: register.postDeregister(); 2107: } 2108: 2109: private void notify(ObjectName name, String type) 2110: { 2111: delegate.sendNotification 2112: (new MBeanServerNotification 2113: (type, DELEGATE_NAME, sequenceNumber.getAndIncrement(), name)); 2114: } 2115: 2116: /** 2117: * Input stream which deserializes using the given classloader. 2118: */ 2119: private class ServerInputStream 2120: extends ObjectInputStream 2121: { 2122: 2123: private ClassLoader cl; 2124: 2125: public ServerInputStream(InputStream is, ClassLoader cl) 2126: throws IOException, StreamCorruptedException 2127: { 2128: super(is); 2129: this.cl = cl; 2130: } 2131: 2132: protected Class resolveClass(ObjectStreamClass osc) 2133: throws ClassNotFoundException, IOException 2134: { 2135: try 2136: { 2137: return Class.forName(osc.getName(), true, cl); 2138: } 2139: catch (ClassNotFoundException e) 2140: { 2141: return super.resolveClass(osc); 2142: } 2143: } 2144: 2145: } 2146: 2147: /** 2148: * Holder for information on registered beans. 2149: */ 2150: private class ServerInfo 2151: { 2152: private ObjectInstance instance; 2153: 2154: private Object object; 2155: 2156: public ServerInfo(ObjectInstance instance, Object object) 2157: { 2158: this.instance = instance; 2159: this.object = object; 2160: } 2161: 2162: public Object getObject() 2163: { 2164: return object; 2165: } 2166: 2167: public ObjectInstance getInstance() 2168: { 2169: return instance; 2170: } 2171: } 2172: 2173: /** 2174: * Notification listener which removes direct references 2175: * to beans. 2176: */ 2177: private class ServerNotificationListener 2178: implements NotificationListener 2179: { 2180: 2181: /** 2182: * The bean from which notifications are emitted. 2183: */ 2184: Object bean; 2185: 2186: /** 2187: * The {@link ObjectName} of the emitting bean. 2188: */ 2189: ObjectName name; 2190: 2191: /** 2192: * The real {@link NotificationListener}. 2193: */ 2194: NotificationListener listener; 2195: 2196: /** 2197: * Constructs a new {@link ServerNotificationListener} replacing 2198: * occurrences of <code>bean</code> with its name. 2199: * 2200: * @param bean the bean emitting notifications. 2201: * @param name the object name of the emitting bean. 2202: * @param listener the listener events eventually reach. 2203: */ 2204: public ServerNotificationListener(Object bean, ObjectName name, 2205: NotificationListener listener) 2206: { 2207: this.bean = bean; 2208: this.name = name; 2209: this.listener = listener; 2210: } 2211: 2212: /** 2213: * Replace a direct reference to <code>bean</code> with its 2214: * object reference, if necessary, before calling the listener. 2215: * 2216: * @param notif the notification being emitted. 2217: * @param handback an object that will be returned to the notification 2218: * listener when an event occurs. 2219: */ 2220: public void handleNotification(Notification notif, Object handback) 2221: { 2222: if (notif.getSource() == bean) 2223: notif.setSource(name); 2224: listener.handleNotification(notif, handback); 2225: } 2226: 2227: } 2228: 2229: }