1 /* StandardMBean.java -- A standard reflection-based management bean.
2 Copyright (C) 2006 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
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)
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.
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
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
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. */
38 package javax.management;
40 import java.lang.reflect.Constructor;
41 import java.lang.reflect.InvocationTargetException;
42 import java.lang.reflect.Method;
44 import java.util.ArrayList;
45 import java.util.HashMap;
46 import java.util.Iterator;
47 import java.util.List;
51 * Provides a dynamic management bean by using reflection on an
52 * interface and an implementing class. By default, a bean instance
53 * is paired up with its interface based on specific naming
54 * conventions (if the implementation is called X, the interface must
55 * be XMBean). Using this class removes the need to use a specific
56 * naming system to match up the two. Instead, an instance of this
57 * bean is created either via explicit construction or subclassing,
58 * and this provides access to the attributes, constructors and
59 * operations of the implementation via reflection. Various hooks are
60 * provided in order to allow customization of this process.
62 * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
65 public class StandardMBean
66 implements DynamicMBean
70 * The interface for this bean.
75 * The implementation of the interface.
80 * Cached bean information.
82 private MBeanInfo info;
85 * Constructs a new {@link StandardMBean} using the specified
86 * interface and <code>this</code> as the instance. This should
87 * be used to create an instance via subclassing.
89 * @param iface the interface this bean implements, or <code>null</code>
90 * if the interface should be determined using the naming
91 * convention (class X has interface XMBean).
92 * @throws NotCompliantMBeanException if this class doesn't implement
93 * the interface or a method appears
94 * in the interface that doesn't comply
95 * with the naming conventions.
97 protected StandardMBean(Class iface)
98 throws NotCompliantMBeanException
102 String className = getClass().getName();
105 iface = Class.forName(className + "MBean");
107 catch (ClassNotFoundException e)
109 throw (NotCompliantMBeanException)
110 (new NotCompliantMBeanException("An interface, " + className +
111 "MBean, for the class " + className +
112 " was not found.").initCause(e));
115 if (!(iface.isInstance(this)))
116 throw new NotCompliantMBeanException("The instance, " + impl +
117 ", is not an instance of " + iface);
123 * Constructs a new {@link StandardMBean} using the specified
124 * interface and the supplied instance as the implementation.
126 * @param impl the implementation.
127 * @param iface the interface the bean implements, or <code>null</code>
128 * if the interface should be determined using the naming
129 * convention (class X has interface XMBean).
130 * @throws IllegalArgumentException if <code>impl</code> is <code>null</code>.
131 * @throws NotCompliantMBeanException if <code>impl</code> doesn't implement
132 * the interface or a method appears
133 * in the interface that doesn't comply
134 * with the naming conventions.
136 public StandardMBean(Object impl, Class iface)
137 throws NotCompliantMBeanException
140 throw new IllegalArgumentException("The specified implementation is null.");
143 String className = impl.getClass().getName();
146 iface = Class.forName(className + "MBean", true,
147 impl.getClass().getClassLoader());
149 catch (ClassNotFoundException e)
151 throw (NotCompliantMBeanException)
152 (new NotCompliantMBeanException("An interface, " + className +
153 "MBean, for the class " + className +
154 " was not found.").initCause(e));
157 if (!(iface.isInstance(impl)))
158 throw new NotCompliantMBeanException("The instance, " + impl +
159 ", is not an instance of " + iface);
165 * Caches the {@link MBeanInfo} instance for this object. This is a
166 * customization hook, so that subclasses can choose the caching policy
167 * used. The default implementation caches the value in the instance
168 * itself. Subclasses may override this so as to not cache the data
169 * at all, or so as to use a cache shared between multiple beans.
171 * @param info the {@link MBeanInfo} instance to cache, or <code>null</code>
172 * if there is no new value to cache. When the value is not
173 * <code>null</code>, the cache should replace the current value
174 * with the value supplied here.
175 * @see #getCachedMBeanInfo()
177 protected void cacheMBeanInfo(MBeanInfo info)
184 * Obtains the value of the specified attribute of the
185 * management bean. The management bean should perform
186 * a lookup for the named attribute, and return its value
187 * by calling the appropriate getter method, if possible.
189 * @param name the name of the attribute to retrieve.
190 * @return the value of the specified attribute.
191 * @throws AttributeNotFoundException if the name does not
192 * correspond to an attribute
194 * @throws MBeanException if retrieving the attribute causes
195 * the bean to throw an exception (which
196 * becomes the cause of this exception).
197 * @throws ReflectionException if an exception occurred in trying
198 * to use the reflection interface
199 * to lookup the attribute. The
200 * thrown exception is the cause of
202 * @see #setAttribute(String)
204 public Object getAttribute(String name)
205 throws AttributeNotFoundException, MBeanException,
211 getter = iface.getMethod("get" + name, null);
213 catch (NoSuchMethodException e)
217 getter = iface.getMethod("is" + name, null);
219 catch (NoSuchMethodException ex)
221 throw ((AttributeNotFoundException)
222 new AttributeNotFoundException("The attribute, " + name +
223 ", was not found.").initCause(ex));
229 result = getter.invoke(impl, null);
231 catch (IllegalAccessException e)
233 throw new ReflectionException(e, "Failed to retrieve " + name);
235 catch (IllegalArgumentException e)
237 throw new ReflectionException(e, "Failed to retrieve " + name);
239 catch (InvocationTargetException e)
241 throw new MBeanException((Exception) e.getCause(),
242 "The getter of " + name +
243 " threw an exception");
249 * Obtains the values of each of the specified attributes
250 * of the management bean. The returned list includes
251 * those attributes that were retrieved and their
252 * corresponding values.
254 * @param names the names of the attributes to retrieve.
255 * @return a list of the retrieved attributes.
256 * @see #setAttributes(AttributeList)
258 public AttributeList getAttributes(String[] names)
260 AttributeList list = new AttributeList(names.length);
261 for (int a = 0; a < names.length; ++a)
265 Object value = getAttribute(names[a]);
266 list.add(new Attribute(names[a], value));
268 catch (AttributeNotFoundException e)
272 catch (ReflectionException e)
276 catch (MBeanException e)
285 * Returns the cached {@link MBeanInfo} instance for this object. This is a
286 * customization hook, so that subclasses can choose the caching policy
287 * used. The default implementation caches the value in the instance
288 * itself, and returns this value on calls to this method.
290 * @return the cached {@link MBeanInfo} instance, or <code>null</code>
291 * if no value is cached.
292 * @see #cacheMBeanInfo(javax.management.MBeanInfo)
294 protected MBeanInfo getCachedMBeanInfo()
300 * Returns the class name that will be used in the {@link MBeanInfo}
301 * instance. This is a customization hook, so that subclasses can
302 * provide a custom class name. By default, this returns the class
303 * name from the supplied {@link MBeanInfo} instance.
305 * @param info the {@link MBeanInfo} instance constructed via
307 * @return the class name to use in the instance.
309 protected String getClassName(MBeanInfo info)
311 return info.getClassName();
315 * Returns information on the constructors that will be used in
316 * the {@link MBeanInfo} instance. This is a customization hook,
317 * so that subclasses can provide their own information on the
318 * bean's constructors, if necessary. By default, this method
319 * returns <code>null</code> unless the implementation supplied
320 * is either <code>null</code> or <code>this</code>. This default
321 * implementation prevents the use of
322 * {@link MBeanServer#createMBean} in cases where the bean is
323 * not created as a subclass of {@link StandardMBean}.
325 * @param constructors the constructor information created via
327 * @param impl the implementation, or <code>null</code> if this
329 * @return the constructor information to use.
331 protected MBeanConstructorInfo[] getConstructors(MBeanConstructorInfo[]
332 constructors, Object impl)
334 if (impl == null || impl == this)
340 * Returns the description of the attribute that will be used in
341 * the supplied {@link MBeanAttributeInfo} instance. This is a
342 * customization hook, so that subclasses can provide a custom
343 * description. By default, this calls
344 * {@link #getDescription(MBeanFeatureInfo)} with the supplied
345 * {@link MBeanAttributeInfo} instance.
347 * @param info the {@link MBeanAttributeInfo} instance constructed
349 * @return the description to use in the instance.
351 protected String getDescription(MBeanAttributeInfo info)
353 return getDescription((MBeanFeatureInfo) info);
357 * Returns the description of the constructor that will be used in
358 * the supplied {@link MBeanConstructorInfo} instance. This is a
359 * customization hook, so that subclasses can provide a custom
360 * description. By default, this calls
361 * {@link #getDescription(MBeanFeatureInfo)} with the supplied
362 * {@link MBeanConstructorInfo} instance.
364 * @param info the {@link MBeanConstructorInfo} instance constructed
366 * @return the description to use in the instance.
368 protected String getDescription(MBeanConstructorInfo info)
370 return getDescription((MBeanFeatureInfo) info);
374 * Returns the description of the nth parameter of the constructor
375 * that will be used in the supplied {@link MBeanParameterInfo}
376 * instance. This is a customization hook, so that subclasses
377 * can provide a custom description. By default, this calls
378 * <code>param.getDescription()</code>.
380 * @param info the {@link MBeanConstructorInfo} instance constructed
382 * @param param the {@link MBeanParameterInfo} instance constructed
384 * @param n the number of the parameter, in order to link it to the
385 * information on the constructor.
386 * @return the description to use in the instance.
388 protected String getDescription(MBeanConstructorInfo info,
389 MBeanParameterInfo param, int n)
391 return param.getDescription();
395 * Returns the description of the supplied feature that
396 * will be used in the supplied {@link MBeanFeatureInfo}
397 * instance. This is a customization hook, so that subclasses
398 * can provide a custom description. By default, this calls
399 * <code>info.getDescription()</code>. This method is also called
400 * by default for the more specific description methods for attributes,
401 * constructors and operations.
403 * @param info the {@link MBeanFeatureInfo} instance constructed
405 * @return the description to use in the instance.
407 protected String getDescription(MBeanFeatureInfo info)
409 return info.getDescription();
413 * Returns the description of the bean that will be used in the
414 * supplied {@link MBeanInfo} instance. This is a customization
415 * hook, so that subclasses can provide a custom description. By
416 * default, this calls <code>info.getDescription()</code>.
418 * @param info the {@link MBeanInfo} instance constructed
420 * @return the description to use in the instance.
422 protected String getDescription(MBeanInfo info)
424 return info.getDescription();
428 * Returns the description of the operation that will be used in
429 * the supplied {@link MBeanOperationInfo} instance. This is a
430 * customization hook, so that subclasses can provide a custom
431 * description. By default, this calls
432 * {@link #getDescription(MBeanFeatureInfo)} with the supplied
433 * {@link MBeanOperationInfo} instance.
435 * @param info the {@link MBeanOperationInfo} instance constructed
437 * @return the description to use in the instance.
439 protected String getDescription(MBeanOperationInfo info)
441 return getDescription((MBeanFeatureInfo) info);
445 * Returns the description of the nth parameter of the operation
446 * that will be used in the supplied {@link MBeanParameterInfo}
447 * instance. This is a customization hook, so that subclasses
448 * can provide a custom description. By default, this calls
449 * <code>param.getDescription()</code>.
451 * @param info the {@link MBeanOperationInfo} instance constructed
453 * @param param the {@link MBeanParameterInfo} instance constructed
455 * @param n the number of the parameter, in order to link it to the
456 * information on the operation.
457 * @return the description to use in the instance.
459 protected String getDescription(MBeanOperationInfo info,
460 MBeanParameterInfo param, int n)
462 return param.getDescription();
466 * Returns the impact of the operation that will be used in the
467 * supplied {@link MBeanOperationInfo} instance. This is a
468 * customization hook, so that subclasses can provide a custom
469 * impact flag. By default, this returns
470 * <code>info.getImpact()</code>.
472 * @param info the {@link MBeanOperationInfo} instance constructed
474 * @return the impact flag to use in the instance.
476 protected int getImpact(MBeanOperationInfo info)
478 return info.getImpact();
482 * Returns the instance that implements this bean.
484 * @return the implementation.
486 public Object getImplementation()
492 * Returns the class of the instance that implements this bean.
494 * @return the implementation class.
496 public Class getImplementationClass()
498 return impl.getClass();
503 * Returns an information object which lists the attributes
504 * and actions associated with the management bean. This
505 * implementation proceeds as follows:
508 * <li>{@link #getCachedMBeanInfo()} is called to obtain
509 * the cached instance. If this returns a non-null value,
510 * this value is returned.</li>
511 * <li>If there is no cached value, then the method proceeds
512 * to create one. During this process, the customization hooks
513 * detailed in this class are called to allow the values used
516 * <li>For each attribute,
517 * {@link #getDescription(MBeanAttributeInfo)} is called.</li>
518 * <li>For each constructor,
519 * {@link #getDescription(MBeanConstructorInfo)} is called,
520 * along with {@link #getDescription(MBeanConstructorInfo,
521 * MBeanParameterInfo, int)} and
522 * {@link #getParameterName(MBeanConstructorInfo,
523 * MBeanParameterInfo, int)} for each parameter.</li>
524 * <li>The constructors may be replaced as a whole by
526 * {@link #getConstructors(MBeanConstructorInfo[], Object)}.</li>
527 * <li>For each operation,
528 * {@link #getDescription(MBeanOperationInfo)} and
529 * {@link #getImpact(MBeanOperationInfo)} are called,
530 * along with {@link #getDescription(MBeanOperationInfo,
531 * MBeanParameterInfo, int)} and
532 * {@link #getParameterName(MBeanOperationInfo,
533 * MBeanParameterInfo, int)} for each parameter.</li>
534 * <li>{@link #getClassName(MBeanInfo)} and
535 * {@link #getDescription(MBeanInfo)} are called to customise
536 * the basic information about the class.</li>
539 * <li>Finally, {@link #cacheMBeanInfo(MBeanInfo)} is called
540 * with the created instance before it is returned.</li>
543 * @return a description of the management bean, including
544 * all exposed attributes and actions.
546 public MBeanInfo getMBeanInfo()
548 MBeanInfo info = getCachedMBeanInfo();
551 Method[] methods = iface.getMethods();
552 Map attributes = new HashMap();
553 List operations = new ArrayList();
554 for (int a = 0; a < methods.length; ++a)
556 String name = methods[a].getName();
557 if (((name.startsWith("get") &&
558 methods[a].getReturnType() != Void.TYPE) ||
559 (name.startsWith("is") &&
560 methods[a].getReturnType() == Boolean.TYPE)) &&
561 methods[a].getParameterTypes().length == 0)
565 if (name.startsWith("is"))
566 attrib = name.substring(2);
568 attrib = name.substring(3);
569 if (attributes.containsKey(attrib))
570 amethods = (Method[]) attributes.get(attrib);
573 amethods = new Method[2];
574 attributes.put(attrib, amethods);
576 amethods[0] = methods[a];
578 else if (name.startsWith("set") &&
579 methods[a].getReturnType() == Void.TYPE &&
580 methods[a].getParameterTypes().length == 1)
583 String attrib = name.substring(3);
584 if (attributes.containsKey(attrib))
585 amethods = (Method[]) attributes.get(attrib);
588 amethods = new Method[2];
589 attributes.put(attrib, amethods);
591 amethods[1] = methods[a];
594 operations.add(new MBeanOperationInfo(methods[a].getName(),
597 List attribs = new ArrayList(attributes.size());
598 Iterator it = attributes.entrySet().iterator();
601 Map.Entry entry = (Map.Entry) it.next();
602 Method[] amethods = (Method[]) entry.getValue();
605 attribs.add(new MBeanAttributeInfo((String) entry.getKey(),
606 (String) entry.getKey(),
607 amethods[0], amethods[1]));
609 catch (IntrospectionException e)
611 /* Shouldn't happen; both shouldn't be null */
612 throw new IllegalStateException("The two methods passed to " +
613 "the MBeanAttributeInfo " +
614 "constructor for " + entry +
618 MBeanAttributeInfo[] ainfo = new MBeanAttributeInfo[attribs.size()];
619 for (int a = 0; a < ainfo.length; ++a)
621 MBeanAttributeInfo oldInfo = (MBeanAttributeInfo) attribs.get(a);
622 String desc = getDescription(oldInfo);
623 ainfo[a] = new MBeanAttributeInfo(oldInfo.getName(),
624 oldInfo.getType(), desc,
625 oldInfo.isReadable(),
626 oldInfo.isWritable(),
629 Constructor[] cons = impl.getClass().getConstructors();
630 MBeanConstructorInfo[] cinfo = new MBeanConstructorInfo[cons.length];
631 for (int a = 0; a < cinfo.length; ++a)
633 MBeanConstructorInfo oldInfo = new MBeanConstructorInfo(cons[a].getName(),
635 String desc = getDescription(oldInfo);
636 MBeanParameterInfo[] params = oldInfo.getSignature();
637 MBeanParameterInfo[] pinfo = new MBeanParameterInfo[params.length];
638 for (int b = 0; b < pinfo.length; ++b)
640 String pdesc = getDescription(oldInfo, params[b], b);
641 String pname = getParameterName(oldInfo, params[b], b);
642 pinfo[b] = new MBeanParameterInfo(pname, params[b].getType(),
645 cinfo[a] = new MBeanConstructorInfo(oldInfo.getName(), desc,
648 cinfo = getConstructors(cinfo, impl);
649 MBeanOperationInfo[] oinfo = new MBeanOperationInfo[operations.size()];
650 for (int a = 0; a < oinfo.length; ++a)
652 MBeanOperationInfo oldInfo = (MBeanOperationInfo) operations.get(a);
653 String desc = getDescription(oldInfo);
654 int impact = getImpact(oldInfo);
655 MBeanParameterInfo[] params = oldInfo.getSignature();
656 MBeanParameterInfo[] pinfo = new MBeanParameterInfo[params.length];
657 for (int b = 0; b < pinfo.length; ++b)
659 String pdesc = getDescription(oldInfo, params[b], b);
660 String pname = getParameterName(oldInfo, params[b], b);
661 pinfo[b] = new MBeanParameterInfo(pname, params[b].getType(),
664 oinfo[a] = new MBeanOperationInfo(oldInfo.getName(), desc, pinfo,
665 oldInfo.getReturnType(), impact);
667 info = new MBeanInfo(impl.getClass().getName(), impl.getClass().getName(),
668 ainfo, cinfo, oinfo, null);
669 String cname = getClassName(info);
670 String desc = getDescription(info);
671 MBeanNotificationInfo[] ninfo = null;
672 if (impl instanceof NotificationBroadcaster)
673 ninfo = ((NotificationBroadcaster) impl).getNotificationInfo();
674 info = new MBeanInfo(cname, desc, ainfo, cinfo, oinfo, ninfo);
675 cacheMBeanInfo(info);
680 * Returns the interface for this management bean.
682 * @return the management interface.
684 public final Class getMBeanInterface()
690 * Returns the name of the nth parameter of the constructor
691 * that will be used in the supplied {@link MBeanParameterInfo}
692 * instance. This is a customization hook, so that subclasses
693 * can provide a custom name. By default, this calls
694 * <code>param.getName()</code>.
696 * @param info the {@link MBeanConstructorInfo} instance constructed
698 * @param param the {@link MBeanParameterInfo} instance constructed
700 * @param n the number of the parameter, in order to link it to the
701 * information on the constructor.
702 * @return the name to use in the instance.
704 protected String getParameterName(MBeanConstructorInfo info,
705 MBeanParameterInfo param, int n)
707 return param.getName();
711 * Returns the name of the nth parameter of the operation
712 * that will be used in the supplied {@link MBeanParameterInfo}
713 * instance. This is a customization hook, so that subclasses
714 * can provide a custom name. By default, this calls
715 * <code>param.getName()</code>.
717 * @param info the {@link MBeanOperationInfo} instance constructed
719 * @param param the {@link MBeanParameterInfo} instance constructed
721 * @param n the number of the parameter, in order to link it to the
722 * information on the operation.
723 * @return the name to use in the instance.
725 protected String getParameterName(MBeanOperationInfo info,
726 MBeanParameterInfo param, int n)
728 return param.getName();
732 * Invokes the specified action on the management bean using
733 * the supplied parameters. The signature of the action is
734 * specified by a {@link String} array, which lists the classes
735 * corresponding to each parameter. The class loader used to
736 * load these classes is the same as that used for loading the
737 * management bean itself.
739 * @param name the name of the action to invoke.
740 * @param params the parameters used to call the action.
741 * @param signature the signature of the action.
742 * @return the return value of the action.
743 * @throws MBeanException if the action throws an exception. The
744 * thrown exception is the cause of this
746 * @throws ReflectionException if an exception occurred in trying
747 * to use the reflection interface
748 * to invoke the action. The
749 * thrown exception is the cause of
752 public Object invoke(String name, Object[] params, String[] signature)
753 throws MBeanException, ReflectionException
755 Class[] sigTypes = new Class[signature.length];
756 ClassLoader loader = getClass().getClassLoader();
757 for (int a = 0; a < signature.length; ++a)
760 sigTypes[a] = Class.forName(signature[a], true, loader);
762 catch (ClassNotFoundException e)
764 throw new ReflectionException(e, "The class, " + signature[a] +
765 ", in the method signature " +
766 "could not be loaded.");
771 method = iface.getMethod(name, sigTypes);
773 catch (NoSuchMethodException e)
775 throw new ReflectionException(e, "The method, " + name +
776 ", could not be found.");
781 result = method.invoke(impl, params);
783 catch (IllegalAccessException e)
785 throw new ReflectionException(e, "Failed to call " + name);
787 catch (IllegalArgumentException e)
789 throw new ReflectionException(e, "Failed to call " + name);
791 catch (InvocationTargetException e)
793 throw new MBeanException((Exception) e.getCause(), "The method "
794 + name + " threw an exception");
800 * Sets the value of the specified attribute of the
801 * management bean. The management bean should perform
802 * a lookup for the named attribute, and sets its value
803 * using the associated setter method, if possible.
805 * @param attribute the attribute to set.
806 * @throws AttributeNotFoundException if the attribute does not
807 * correspond to an attribute
809 * @throws InvalidAttributeValueException if the value is invalid
810 * for this particular
811 * attribute of the bean.
812 * @throws MBeanException if setting the attribute causes
813 * the bean to throw an exception (which
814 * becomes the cause of this exception).
815 * @throws ReflectionException if an exception occurred in trying
816 * to use the reflection interface
817 * to lookup the attribute. The
818 * thrown exception is the cause of
820 * @see #getAttribute(String)
822 public void setAttribute(Attribute attribute)
823 throws AttributeNotFoundException, InvalidAttributeValueException,
824 MBeanException, ReflectionException
827 String name = attribute.getName();
830 setter = iface.getMethod("set" +
831 name.substring(0, 1).toUpperCase() +
832 name.substring(1), null);
834 catch (NoSuchMethodException e)
836 throw ((AttributeNotFoundException)
837 new AttributeNotFoundException("The attribute, " + name +
838 ", was not found.").initCause(e));
842 setter.invoke(impl, new Object[] { attribute.getValue() });
844 catch (IllegalAccessException e)
846 throw new ReflectionException(e, "Failed to set " + name);
848 catch (IllegalArgumentException e)
850 throw ((InvalidAttributeValueException)
851 new InvalidAttributeValueException(attribute.getValue() +
852 " is an invalid value for " +
855 catch (InvocationTargetException e)
857 throw new MBeanException((Exception) e.getCause(), "The getter of "
858 + name + " threw an exception");
863 * Sets the value of each of the specified attributes
864 * to that supplied by the {@link Attribute} object.
865 * The returned list contains the attributes that were
866 * set and their new values.
868 * @param attributes the attributes to set.
869 * @return a list of the changed attributes.
870 * @see #getAttributes(AttributeList)
872 public AttributeList setAttributes(AttributeList attributes)
874 AttributeList list = new AttributeList(attributes.size());
875 Iterator it = attributes.iterator();
880 Attribute attrib = (Attribute) it.next();
881 setAttribute(attrib);
884 catch (AttributeNotFoundException e)
888 catch (InvalidAttributeValueException e)
892 catch (ReflectionException e)
896 catch (MBeanException e)
905 * Replaces the implementation of the interface used by this
906 * instance with the one specified. The new implementation
907 * must be non-null and implement the interface specified on
908 * construction of this instance.
910 * @throws IllegalArgumentException if <code>impl</code> is <code>null</code>.
911 * @throws NotCompliantMBeanException if <code>impl</code> doesn't implement
912 * the interface or a method appears
913 * in the interface that doesn't comply
914 * with the naming conventions.
916 public void setImplementation(Object impl)
917 throws NotCompliantMBeanException
920 throw new IllegalArgumentException("The specified implementation is null.");
921 if (!(iface.isInstance(impl)))
922 throw new NotCompliantMBeanException("The instance, " + impl +
923 ", is not an instance of " + iface);