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