/* * Copyright (c) 2002, 2008, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package javax.management; import static com.sun.jmx.defaults.JmxProperties.MISC_LOGGER;import com.sun.jmx.mbeanserver.DescriptorCache;import com.sun.jmx.mbeanserver.Introspector;import com.sun.jmx.mbeanserver.MBeanSupport;import com.sun.jmx.mbeanserver.MXBeanSupport;import com.sun.jmx.mbeanserver.StandardMBeanSupport;import com.sun.jmx.mbeanserver.Util; import java.security.AccessController;import java.security.PrivilegedAction;import java.util.HashMap;import java.util.Map;import java.util.WeakHashMap;import java.util.logging.Level;import javax.management.openmbean.OpenMBeanAttributeInfo;import javax.management.openmbean.OpenMBeanAttributeInfoSupport;import javax.management.openmbean.OpenMBeanConstructorInfo;import javax.management.openmbean.OpenMBeanConstructorInfoSupport;import javax.management.openmbean.OpenMBeanOperationInfo;import javax.management.openmbean.OpenMBeanOperationInfoSupport;import javax.management.openmbean.OpenMBeanParameterInfo;import javax.management.openmbean.OpenMBeanParameterInfoSupport; /** * <p>An MBean whose management interface is determined by reflection * on a Java interface.</p> * * <p>This class brings more flexibility to the notion of Management * Interface in the use of Standard MBeans. Straightforward use of * the patterns for Standard MBeans described in the JMX Specification * means that there is a fixed relationship between the implementation * class of an MBean and its management interface (i.e., if the * implementation class is Thing, the management interface must be * ThingMBean). This class makes it possible to keep the convenience * of specifying the management interface with a Java interface, * without requiring that there be any naming relationship between the * implementation and interface classes.</p> * * <p>By making a DynamicMBean out of an MBean, this class makes * it possible to select any interface implemented by the MBean as its * management interface, provided that it complies with JMX patterns * (i.e., attributes defined by getter/setter etc...).</p> * * <p> This class also provides hooks that make it possible to supply * custom descriptions and names for the {@link MBeanInfo} returned by * the DynamicMBean interface.</p> * * <p>Using this class, an MBean can be created with any * implementation class name <i>Impl</i> and with a management * interface defined (as for current Standard MBeans) by any interface * <i>Intf</i>, in one of two general ways:</p> * * <ul> * * <li>Using the public constructor * {@link #StandardMBean(java.lang.Object, java.lang.Class, boolean) * StandardMBean(impl,interface)}: * <pre> * MBeanServer mbs; * ... * Impl impl = new Impl(...); * StandardMBean mbean = new StandardMBean(impl, Intf.class, false); * mbs.registerMBean(mbean, objectName); * </pre></li> * * <li>Subclassing StandardMBean: * <pre> * public class Impl extends StandardMBean implements Intf { * public Impl() { * super(Intf.class, false); * } * // implement methods of Intf * } * * [...] * * MBeanServer mbs; * .... * Impl impl = new Impl(); * mbs.registerMBean(impl, objectName); * </pre></li> * * </ul> * * <p>In either case, the class <i>Impl</i> must implement the * interface <i>Intf</i>.</p> * * <p>Standard MBeans based on the naming relationship between * implementation and interface classes are of course still * available.</p> * * <p>This class may also be used to construct MXBeans. The usage * is exactly the same as for Standard MBeans except that in the * examples above, the {@code false} parameter to the constructor or * {@code super(...)} invocation is instead {@code true}.</p> * * @since 1.5 */public class StandardMBean implements DynamicMBean, MBeanRegistration { private final static DescriptorCache descriptors = DescriptorCache.getInstance(JMX.proof); /** * The DynamicMBean that wraps the MXBean or Standard MBean implementation. **/ private volatile MBeanSupport<?> mbean; /** * The cached MBeanInfo. **/ private volatile MBeanInfo cachedMBeanInfo; /** * Make a DynamicMBean out of <var>implementation</var>, using the * specified <var>mbeanInterface</var> class. * @param implementation The implementation of this MBean. * If <code>null</code>, and null implementation is allowed, * then the implementation is assumed to be <var>this</var>. * @param mbeanInterface The Management Interface exported by this * MBean's implementation. If <code>null</code>, then this * object will use standard JMX design pattern to determine * the management interface associated with the given * implementation. * @param nullImplementationAllowed <code>true</code> if a null * implementation is allowed. If null implementation is allowed, * and a null implementation is passed, then the implementation * is assumed to be <var>this</var>. * @exception IllegalArgumentException if the given * <var>implementation</var> is null, and null is not allowed. **/ private <T> void construct(T implementation, Class<T> mbeanInterface, boolean nullImplementationAllowed, boolean isMXBean) throws NotCompliantMBeanException { if (implementation == null) { // Have to use (T)this rather than mbeanInterface.cast(this) // because mbeanInterface might be null. if (nullImplementationAllowed) implementation = Util.<T>cast(this); else throw new IllegalArgumentException("implementation is null"); } if (isMXBean) { if (mbeanInterface == null) { mbeanInterface = Util.cast(Introspector.getMXBeanInterface( implementation.getClass())); } this.mbean = new MXBeanSupport(implementation, mbeanInterface); } else { if (mbeanInterface == null) { mbeanInterface = Util.cast(Introspector.getStandardMBeanInterface( implementation.getClass())); } this.mbean = new StandardMBeanSupport(implementation, mbeanInterface); } } /** * <p>Make a DynamicMBean out of the object * <var>implementation</var>, using the specified * <var>mbeanInterface</var> class.</p> * * @param implementation The implementation of this MBean. * @param mbeanInterface The Management Interface exported by this * MBean's implementation. If <code>null</code>, then this * object will use standard JMX design pattern to determine * the management interface associated with the given * implementation. * @param <T> Allows the compiler to check * that {@code implementation} does indeed implement the class * described by {@code mbeanInterface}. The compiler can only * check this if {@code mbeanInterface} is a class literal such * as {@code MyMBean.class}. * * @exception IllegalArgumentException if the given * <var>implementation</var> is null. * @exception NotCompliantMBeanException if the <var>mbeanInterface</var> * does not follow JMX design patterns for Management Interfaces, or * if the given <var>implementation</var> does not implement the * specified interface. **/ public <T> StandardMBean(T implementation, Class<T> mbeanInterface) throws NotCompliantMBeanException { construct(implementation, mbeanInterface, false, false); } /** * <p>Make a DynamicMBean out of <var>this</var>, using the specified * <var>mbeanInterface</var> class.</p> * * <p>Calls {@link #StandardMBean(java.lang.Object, java.lang.Class) * this(this,mbeanInterface)}. * This constructor is reserved to subclasses.</p> * * @param mbeanInterface The Management Interface exported by this * MBean. * * @exception NotCompliantMBeanException if the <var>mbeanInterface</var> * does not follow JMX design patterns for Management Interfaces, or * if <var>this</var> does not implement the specified interface. **/ protected StandardMBean(Class<?> mbeanInterface) throws NotCompliantMBeanException { construct(null, mbeanInterface, true, false); } /** * <p>Make a DynamicMBean out of the object * <var>implementation</var>, using the specified * <var>mbeanInterface</var> class, and choosing whether the * resultant MBean is an MXBean. This constructor can be used * to make either Standard MBeans or MXBeans. Unlike the * constructor {@link #StandardMBean(Object, Class)}, it * does not throw NotCompliantMBeanException.</p> * * @param implementation The implementation of this MBean. * @param mbeanInterface The Management Interface exported by this * MBean's implementation. If <code>null</code>, then this * object will use standard JMX design pattern to determine * the management interface associated with the given * implementation. * @param isMXBean If true, the {@code mbeanInterface} parameter * names an MXBean interface and the resultant MBean is an MXBean. * @param <T> Allows the compiler to check * that {@code implementation} does indeed implement the class * described by {@code mbeanInterface}. The compiler can only * check this if {@code mbeanInterface} is a class literal such * as {@code MyMBean.class}. * * @exception IllegalArgumentException if the given * <var>implementation</var> is null, or if the <var>mbeanInterface</var> * does not follow JMX design patterns for Management Interfaces, or * if the given <var>implementation</var> does not implement the * specified interface. * * @since 1.6 **/ public <T> StandardMBean(T implementation, Class<T> mbeanInterface, boolean isMXBean) { try { construct(implementation, mbeanInterface, false, isMXBean); } catch (NotCompliantMBeanException e) { throw new IllegalArgumentException(e); } } /** * <p>Make a DynamicMBean out of <var>this</var>, using the specified * <var>mbeanInterface</var> class, and choosing whether the resulting * MBean is an MXBean. This constructor can be used * to make either Standard MBeans or MXBeans. Unlike the * constructor {@link #StandardMBean(Object, Class)}, it * does not throw NotCompliantMBeanException.</p> * * <p>Calls {@link #StandardMBean(java.lang.Object, java.lang.Class, boolean) * this(this, mbeanInterface, isMXBean)}. * This constructor is reserved to subclasses.</p> * * @param mbeanInterface The Management Interface exported by this * MBean. * @param isMXBean If true, the {@code mbeanInterface} parameter * names an MXBean interface and the resultant MBean is an MXBean. * * @exception IllegalArgumentException if the <var>mbeanInterface</var> * does not follow JMX design patterns for Management Interfaces, or * if <var>this</var> does not implement the specified interface. * * @since 1.6 **/ protected StandardMBean(Class<?> mbeanInterface, boolean isMXBean) { try { construct(null, mbeanInterface, true, isMXBean); } catch (NotCompliantMBeanException e) { throw new IllegalArgumentException(e); } } /** * <p>Replace the implementation object wrapped in this object.</p> * * @param implementation The new implementation of this Standard MBean * (or MXBean). The <code>implementation</code> object must implement * the Standard MBean (or MXBean) interface that was supplied when this * <code>StandardMBean</code> was constructed. * * @exception IllegalArgumentException if the given * <var>implementation</var> is null. * * @exception NotCompliantMBeanException if the given * <var>implementation</var> does not implement the * Standard MBean (or MXBean) interface that was * supplied at construction. * * @see #getImplementation **/ public void setImplementation(Object implementation) throws NotCompliantMBeanException { if (implementation == null) throw new IllegalArgumentException("implementation is null"); if (isMXBean()) { this.mbean = new MXBeanSupport(implementation, Util.<Class<Object>>cast(getMBeanInterface())); } else { this.mbean = new StandardMBeanSupport(implementation, Util.<Class<Object>>cast(getMBeanInterface())); } } /** * Get the implementation of this Standard MBean (or MXBean). * @return The implementation of this Standard MBean (or MXBean). * * @see #setImplementation **/ public Object getImplementation() { return mbean.getResource(); } /** * Get the Management Interface of this Standard MBean (or MXBean). * @return The management interface of this Standard MBean (or MXBean). **/ public final Class<?> getMBeanInterface() { return mbean.getMBeanInterface(); } /** * Get the class of the implementation of this Standard MBean (or MXBean). * @return The class of the implementation of this Standard MBean (or MXBean). **/ public Class<?> getImplementationClass() { return mbean.getResource().getClass(); } // ------------------------------------------------------------------ // From the DynamicMBean interface. // ------------------------------------------------------------------ public Object getAttribute(String attribute) throws AttributeNotFoundException, MBeanException, ReflectionException { return mbean.getAttribute(attribute); } // ------------------------------------------------------------------ // From the DynamicMBean interface. // ------------------------------------------------------------------ public void setAttribute(Attribute attribute) throws AttributeNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException { mbean.setAttribute(attribute); } // ------------------------------------------------------------------ // From the DynamicMBean interface. // ------------------------------------------------------------------ public AttributeList getAttributes(String[] attributes) { return mbean.getAttributes(attributes); } // ------------------------------------------------------------------ // From the DynamicMBean interface. // ------------------------------------------------------------------ public AttributeList setAttributes(AttributeList attributes) { return mbean.setAttributes(attributes); } // ------------------------------------------------------------------ // From the DynamicMBean interface. // ------------------------------------------------------------------ public Object invoke(String actionName, Object params[], String signature[]) throws MBeanException, ReflectionException { return mbean.invoke(actionName, params, signature); } /** * Get the {@link MBeanInfo} for this MBean. * <p> * This method implements * {@link javax.management.DynamicMBean#getMBeanInfo() * DynamicMBean.getMBeanInfo()}. * <p> * This method first calls {@link #getCachedMBeanInfo()} in order to * retrieve the cached MBeanInfo for this MBean, if any. If the * MBeanInfo returned by {@link #getCachedMBeanInfo()} is not null, * then it is returned.<br> * Otherwise, this method builds a default MBeanInfo for this MBean, * using the Management Interface specified for this MBean. * <p> * While building the MBeanInfo, this method calls the customization * hooks that make it possible for subclasses to supply their custom * descriptions, parameter names, etc...<br> * Finally, it calls {@link #cacheMBeanInfo(javax.management.MBeanInfo) * cacheMBeanInfo()} in order to cache the new MBeanInfo. * @return The cached MBeanInfo for that MBean, if not null, or a * newly built MBeanInfo if none was cached. **/ public MBeanInfo getMBeanInfo() { try { final MBeanInfo cached = getCachedMBeanInfo(); if (cached != null) return cached; } catch (RuntimeException x) { if (MISC_LOGGER.isLoggable(Level.FINEST)) { MISC_LOGGER.logp(Level.FINEST, MBeanServerFactory.class.getName(), "getMBeanInfo", "Failed to get cached MBeanInfo", x); } } if (MISC_LOGGER.isLoggable(Level.FINER)) { MISC_LOGGER.logp(Level.FINER, MBeanServerFactory.class.getName(), "getMBeanInfo", "Building MBeanInfo for " + getImplementationClass().getName()); } MBeanSupport<?> msupport = mbean; final MBeanInfo bi = msupport.getMBeanInfo(); final Object impl = msupport.getResource(); final boolean immutableInfo = immutableInfo(this.getClass()); final String cname = getClassName(bi); final String text = getDescription(bi); final MBeanConstructorInfo[] ctors = getConstructors(bi,impl); final MBeanAttributeInfo[] attrs = getAttributes(bi); final MBeanOperationInfo[] ops = getOperations(bi); final MBeanNotificationInfo[] ntfs = getNotifications(bi); final Descriptor desc = getDescriptor(bi, immutableInfo); final MBeanInfo nmbi = new MBeanInfo( cname, text, attrs, ctors, ops, ntfs, desc); try { cacheMBeanInfo(nmbi); } catch (RuntimeException x) { if (MISC_LOGGER.isLoggable(Level.FINEST)) { MISC_LOGGER.logp(Level.FINEST, MBeanServerFactory.class.getName(), "getMBeanInfo", "Failed to cache MBeanInfo", x); } } return nmbi; } /** * Customization hook: * Get the className that will be used in the MBeanInfo returned by * this MBean. * <br> * Subclasses may redefine this method in order to supply their * custom class name. The default implementation returns * {@link MBeanInfo#getClassName() info.getClassName()}. * @param info The default MBeanInfo derived by reflection. * @return the class name for the new MBeanInfo. **/ protected String getClassName(MBeanInfo info) { if (info == null) return getImplementationClass().getName(); return info.getClassName(); } /** * Customization hook: * Get the description that will be used in the MBeanInfo returned by * this MBean. * <br> * Subclasses may redefine this method in order to supply their * custom MBean description. The default implementation returnsLines 1–500 of 1237. Load more
/* * Copyright (c) 2002, 2008, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package javax.management; import static com.sun.jmx.defaults.JmxProperties.MISC_LOGGER; import com.sun.jmx.mbeanserver.DescriptorCache; import com.sun.jmx.mbeanserver.Introspector; import com.sun.jmx.mbeanserver.MBeanSupport; import com.sun.jmx.mbeanserver.MXBeanSupport; import com.sun.jmx.mbeanserver.StandardMBeanSupport; import com.sun.jmx.mbeanserver.Util; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.HashMap; import java.util.Map; import java.util.WeakHashMap; import java.util.logging.Level; import javax.management.openmbean.OpenMBeanAttributeInfo; import javax.management.openmbean.OpenMBeanAttributeInfoSupport; import javax.management.openmbean.OpenMBeanConstructorInfo; import javax.management.openmbean.OpenMBeanConstructorInfoSupport; import javax.management.openmbean.OpenMBeanOperationInfo; import javax.management.openmbean.OpenMBeanOperationInfoSupport; import javax.management.openmbean.OpenMBeanParameterInfo; import javax.management.openmbean.OpenMBeanParameterInfoSupport; /** * <p>An MBean whose management interface is determined by reflection * on a Java interface.</p> * * <p>This class brings more flexibility to the notion of Management * Interface in the use of Standard MBeans. Straightforward use of * the patterns for Standard MBeans described in the JMX Specification * means that there is a fixed relationship between the implementation * class of an MBean and its management interface (i.e., if the * implementation class is Thing, the management interface must be * ThingMBean). This class makes it possible to keep the convenience * of specifying the management interface with a Java interface, * without requiring that there be any naming relationship between the * implementation and interface classes.</p> * * <p>By making a DynamicMBean out of an MBean, this class makes * it possible to select any interface implemented by the MBean as its * management interface, provided that it complies with JMX patterns * (i.e., attributes defined by getter/setter etc...).</p> * * <p> This class also provides hooks that make it possible to supply * custom descriptions and names for the {@link MBeanInfo} returned by * the DynamicMBean interface.</p> * * <p>Using this class, an MBean can be created with any * implementation class name <i>Impl</i> and with a management * interface defined (as for current Standard MBeans) by any interface * <i>Intf</i>, in one of two general ways:</p> * * <ul> * * <li>Using the public constructor * {@link #StandardMBean(java.lang.Object, java.lang.Class, boolean) * StandardMBean(impl,interface)}: * <pre> * MBeanServer mbs; * ... * Impl impl = new Impl(...); * StandardMBean mbean = new StandardMBean(impl, Intf.class, false); * mbs.registerMBean(mbean, objectName); * </pre></li> * * <li>Subclassing StandardMBean: * <pre> * public class Impl extends StandardMBean implements Intf { * public Impl() { * super(Intf.class, false); * } * // implement methods of Intf * } * * [...] * * MBeanServer mbs; * .... * Impl impl = new Impl(); * mbs.registerMBean(impl, objectName); * </pre></li> * * </ul> * * <p>In either case, the class <i>Impl</i> must implement the * interface <i>Intf</i>.</p> * * <p>Standard MBeans based on the naming relationship between * implementation and interface classes are of course still * available.</p> * * <p>This class may also be used to construct MXBeans. The usage * is exactly the same as for Standard MBeans except that in the * examples above, the {@code false} parameter to the constructor or * {@code super(...)} invocation is instead {@code true}.</p> * * @since 1.5 */ public class StandardMBean implements DynamicMBean, MBeanRegistration { private final static DescriptorCache descriptors = DescriptorCache.getInstance(JMX.proof); /** * The DynamicMBean that wraps the MXBean or Standard MBean implementation. **/ private volatile MBeanSupport<?> mbean; /** * The cached MBeanInfo. **/ private volatile MBeanInfo cachedMBeanInfo; /** * Make a DynamicMBean out of <var>implementation</var>, using the * specified <var>mbeanInterface</var> class. * @param implementation The implementation of this MBean. * If <code>null</code>, and null implementation is allowed, * then the implementation is assumed to be <var>this</var>. * @param mbeanInterface The Management Interface exported by this * MBean's implementation. If <code>null</code>, then this * object will use standard JMX design pattern to determine * the management interface associated with the given * implementation. * @param nullImplementationAllowed <code>true</code> if a null * implementation is allowed. If null implementation is allowed, * and a null implementation is passed, then the implementation * is assumed to be <var>this</var>. * @exception IllegalArgumentException if the given * <var>implementation</var> is null, and null is not allowed. **/ private <T> void construct(T implementation, Class<T> mbeanInterface, boolean nullImplementationAllowed, boolean isMXBean) throws NotCompliantMBeanException { if (implementation == null) { // Have to use (T)this rather than mbeanInterface.cast(this) // because mbeanInterface might be null. if (nullImplementationAllowed) implementation = Util.<T>cast(this); else throw new IllegalArgumentException("implementation is null"); } if (isMXBean) { if (mbeanInterface == null) { mbeanInterface = Util.cast(Introspector.getMXBeanInterface( implementation.getClass())); } this.mbean = new MXBeanSupport(implementation, mbeanInterface); } else { if (mbeanInterface == null) { mbeanInterface = Util.cast(Introspector.getStandardMBeanInterface( implementation.getClass())); } this.mbean = new StandardMBeanSupport(implementation, mbeanInterface); } } /** * <p>Make a DynamicMBean out of the object * <var>implementation</var>, using the specified * <var>mbeanInterface</var> class.</p> * * @param implementation The implementation of this MBean. * @param mbeanInterface The Management Interface exported by this * MBean's implementation. If <code>null</code>, then this * object will use standard JMX design pattern to determine * the management interface associated with the given * implementation. * @param <T> Allows the compiler to check * that {@code implementation} does indeed implement the class * described by {@code mbeanInterface}. The compiler can only * check this if {@code mbeanInterface} is a class literal such * as {@code MyMBean.class}. * * @exception IllegalArgumentException if the given * <var>implementation</var> is null. * @exception NotCompliantMBeanException if the <var>mbeanInterface</var> * does not follow JMX design patterns for Management Interfaces, or * if the given <var>implementation</var> does not implement the * specified interface. **/ public <T> StandardMBean(T implementation, Class<T> mbeanInterface) throws NotCompliantMBeanException { construct(implementation, mbeanInterface, false, false); } /** * <p>Make a DynamicMBean out of <var>this</var>, using the specified * <var>mbeanInterface</var> class.</p> * * <p>Calls {@link #StandardMBean(java.lang.Object, java.lang.Class) * this(this,mbeanInterface)}. * This constructor is reserved to subclasses.</p> * * @param mbeanInterface The Management Interface exported by this * MBean. * * @exception NotCompliantMBeanException if the <var>mbeanInterface</var> * does not follow JMX design patterns for Management Interfaces, or * if <var>this</var> does not implement the specified interface. **/ protected StandardMBean(Class<?> mbeanInterface) throws NotCompliantMBeanException { construct(null, mbeanInterface, true, false); } /** * <p>Make a DynamicMBean out of the object * <var>implementation</var>, using the specified * <var>mbeanInterface</var> class, and choosing whether the * resultant MBean is an MXBean. This constructor can be used * to make either Standard MBeans or MXBeans. Unlike the * constructor {@link #StandardMBean(Object, Class)}, it * does not throw NotCompliantMBeanException.</p> * * @param implementation The implementation of this MBean. * @param mbeanInterface The Management Interface exported by this * MBean's implementation. If <code>null</code>, then this * object will use standard JMX design pattern to determine * the management interface associated with the given * implementation. * @param isMXBean If true, the {@code mbeanInterface} parameter * names an MXBean interface and the resultant MBean is an MXBean. * @param <T> Allows the compiler to check * that {@code implementation} does indeed implement the class * described by {@code mbeanInterface}. The compiler can only * check this if {@code mbeanInterface} is a class literal such * as {@code MyMBean.class}. * * @exception IllegalArgumentException if the given * <var>implementation</var> is null, or if the <var>mbeanInterface</var> * does not follow JMX design patterns for Management Interfaces, or * if the given <var>implementation</var> does not implement the * specified interface. * * @since 1.6 **/ public <T> StandardMBean(T implementation, Class<T> mbeanInterface, boolean isMXBean) { try { construct(implementation, mbeanInterface, false, isMXBean); } catch (NotCompliantMBeanException e) { throw new IllegalArgumentException(e); } } /** * <p>Make a DynamicMBean out of <var>this</var>, using the specified * <var>mbeanInterface</var> class, and choosing whether the resulting * MBean is an MXBean. This constructor can be used * to make either Standard MBeans or MXBeans. Unlike the * constructor {@link #StandardMBean(Object, Class)}, it * does not throw NotCompliantMBeanException.</p> * * <p>Calls {@link #StandardMBean(java.lang.Object, java.lang.Class, boolean) * this(this, mbeanInterface, isMXBean)}. * This constructor is reserved to subclasses.</p> * * @param mbeanInterface The Management Interface exported by this * MBean. * @param isMXBean If true, the {@code mbeanInterface} parameter * names an MXBean interface and the resultant MBean is an MXBean. * * @exception IllegalArgumentException if the <var>mbeanInterface</var> * does not follow JMX design patterns for Management Interfaces, or * if <var>this</var> does not implement the specified interface. * * @since 1.6 **/ protected StandardMBean(Class<?> mbeanInterface, boolean isMXBean) { try { construct(null, mbeanInterface, true, isMXBean); } catch (NotCompliantMBeanException e) { throw new IllegalArgumentException(e); } } /** * <p>Replace the implementation object wrapped in this object.</p> * * @param implementation The new implementation of this Standard MBean * (or MXBean). The <code>implementation</code> object must implement * the Standard MBean (or MXBean) interface that was supplied when this * <code>StandardMBean</code> was constructed. * * @exception IllegalArgumentException if the given * <var>implementation</var> is null. * * @exception NotCompliantMBeanException if the given * <var>implementation</var> does not implement the * Standard MBean (or MXBean) interface that was * supplied at construction. * * @see #getImplementation **/ public void setImplementation(Object implementation) throws NotCompliantMBeanException { if (implementation == null) throw new IllegalArgumentException("implementation is null"); if (isMXBean()) { this.mbean = new MXBeanSupport(implementation, Util.<Class<Object>>cast(getMBeanInterface())); } else { this.mbean = new StandardMBeanSupport(implementation, Util.<Class<Object>>cast(getMBeanInterface())); } } /** * Get the implementation of this Standard MBean (or MXBean). * @return The implementation of this Standard MBean (or MXBean). * * @see #setImplementation **/ public Object getImplementation() { return mbean.getResource(); } /** * Get the Management Interface of this Standard MBean (or MXBean). * @return The management interface of this Standard MBean (or MXBean). **/ public final Class<?> getMBeanInterface() { return mbean.getMBeanInterface(); } /** * Get the class of the implementation of this Standard MBean (or MXBean). * @return The class of the implementation of this Standard MBean (or MXBean). **/ public Class<?> getImplementationClass() { return mbean.getResource().getClass(); } // ------------------------------------------------------------------ // From the DynamicMBean interface. // ------------------------------------------------------------------ public Object getAttribute(String attribute) throws AttributeNotFoundException, MBeanException, ReflectionException { return mbean.getAttribute(attribute); } // ------------------------------------------------------------------ // From the DynamicMBean interface. // ------------------------------------------------------------------ public void setAttribute(Attribute attribute) throws AttributeNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException { mbean.setAttribute(attribute); } // ------------------------------------------------------------------ // From the DynamicMBean interface. // ------------------------------------------------------------------ public AttributeList getAttributes(String[] attributes) { return mbean.getAttributes(attributes); } // ------------------------------------------------------------------ // From the DynamicMBean interface. // ------------------------------------------------------------------ public AttributeList setAttributes(AttributeList attributes) { return mbean.setAttributes(attributes); } // ------------------------------------------------------------------ // From the DynamicMBean interface. // ------------------------------------------------------------------ public Object invoke(String actionName, Object params[], String signature[]) throws MBeanException, ReflectionException { return mbean.invoke(actionName, params, signature); } /** * Get the {@link MBeanInfo} for this MBean. * <p> * This method implements * {@link javax.management.DynamicMBean#getMBeanInfo() * DynamicMBean.getMBeanInfo()}. * <p> * This method first calls {@link #getCachedMBeanInfo()} in order to * retrieve the cached MBeanInfo for this MBean, if any. If the * MBeanInfo returned by {@link #getCachedMBeanInfo()} is not null, * then it is returned.<br> * Otherwise, this method builds a default MBeanInfo for this MBean, * using the Management Interface specified for this MBean. * <p> * While building the MBeanInfo, this method calls the customization * hooks that make it possible for subclasses to supply their custom * descriptions, parameter names, etc...<br> * Finally, it calls {@link #cacheMBeanInfo(javax.management.MBeanInfo) * cacheMBeanInfo()} in order to cache the new MBeanInfo. * @return The cached MBeanInfo for that MBean, if not null, or a * newly built MBeanInfo if none was cached. **/ public MBeanInfo getMBeanInfo() { try { final MBeanInfo cached = getCachedMBeanInfo(); if (cached != null) return cached; } catch (RuntimeException x) { if (MISC_LOGGER.isLoggable(Level.FINEST)) { MISC_LOGGER.logp(Level.FINEST, MBeanServerFactory.class.getName(), "getMBeanInfo", "Failed to get cached MBeanInfo", x); } } if (MISC_LOGGER.isLoggable(Level.FINER)) { MISC_LOGGER.logp(Level.FINER, MBeanServerFactory.class.getName(), "getMBeanInfo", "Building MBeanInfo for " + getImplementationClass().getName()); } MBeanSupport<?> msupport = mbean; final MBeanInfo bi = msupport.getMBeanInfo(); final Object impl = msupport.getResource(); final boolean immutableInfo = immutableInfo(this.getClass()); final String cname = getClassName(bi); final String text = getDescription(bi); final MBeanConstructorInfo[] ctors = getConstructors(bi,impl); final MBeanAttributeInfo[] attrs = getAttributes(bi); final MBeanOperationInfo[] ops = getOperations(bi); final MBeanNotificationInfo[] ntfs = getNotifications(bi); final Descriptor desc = getDescriptor(bi, immutableInfo); final MBeanInfo nmbi = new MBeanInfo( cname, text, attrs, ctors, ops, ntfs, desc); try { cacheMBeanInfo(nmbi); } catch (RuntimeException x) { if (MISC_LOGGER.isLoggable(Level.FINEST)) { MISC_LOGGER.logp(Level.FINEST, MBeanServerFactory.class.getName(), "getMBeanInfo", "Failed to cache MBeanInfo", x); } } return nmbi; } /** * Customization hook: * Get the className that will be used in the MBeanInfo returned by * this MBean. * <br> * Subclasses may redefine this method in order to supply their * custom class name. The default implementation returns * {@link MBeanInfo#getClassName() info.getClassName()}. * @param info The default MBeanInfo derived by reflection. * @return the class name for the new MBeanInfo. **/ protected String getClassName(MBeanInfo info) { if (info == null) return getImplementationClass().getName(); return info.getClassName(); } /** * Customization hook: * Get the description that will be used in the MBeanInfo returned by * this MBean. * <br> * Subclasses may redefine this method in order to supply their * custom MBean description. The default implementation returns