/*
* Copyright (c) 2002, 2007, 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.io.PrintWriter;
import java.io.StringWriter;
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;
An MBean whose management interface is determined by reflection
on a Java interface.
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.
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...).
This class also provides hooks that make it possible to supply custom descriptions and names for the MBeanInfo
returned by the DynamicMBean interface.
Using this class, an MBean can be created with any
implementation class name Impl and with a management
interface defined (as for current Standard MBeans) by any interface
Intf, in one of two general ways:
- Using the public constructor
StandardMBean(impl,interface)
: MBeanServer mbs;
...
Impl impl = new Impl(...);
StandardMBean mbean = new StandardMBean(impl, Intf.class, false);
mbs.registerMBean(mbean, objectName);
- Subclassing StandardMBean:
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);
In either case, the class Impl must implement the
interface Intf.
Standard MBeans based on the naming relationship between
implementation and interface classes are of course still
available.
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 false
parameter to the constructor or super(...)
invocation is instead true
.
Since: 1.5
/**
* <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.
/**
* The DynamicMBean that wraps the MXBean or Standard MBean implementation.
**/
private volatile MBeanSupport<?> mbean;
The cached MBeanInfo.
/**
* The cached MBeanInfo.
**/
private volatile MBeanInfo cachedMBeanInfo;
Make a DynamicMBean out of implementation, using the
specified mbeanInterface class.
Params: - implementation – The implementation of this MBean.
If
null
, and null implementation is allowed,
then the implementation is assumed to be this. - mbeanInterface – The Management Interface exported by this
MBean's implementation. If
null
, then this
object will use standard JMX design pattern to determine
the management interface associated with the given
implementation. - nullImplementationAllowed –
true
if a null
implementation is allowed. If null implementation is allowed,
and a null implementation is passed, then the implementation
is assumed to be this.
Throws: - IllegalArgumentException – if the given
implementation is null, and null is not allowed.
/**
* 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);
}
}
Make a DynamicMBean out of the object
implementation, using the specified
mbeanInterface class.
Params: - implementation – The implementation of this MBean.
- mbeanInterface – The Management Interface exported by this
MBean's implementation. If
null
, then this
object will use standard JMX design pattern to determine
the management interface associated with the given
implementation.
Type parameters: - <T> – Allows the compiler to check that
implementation
does indeed implement the class described by mbeanInterface
. The compiler can only check this if mbeanInterface
is a class literal such as MyMBean.class
.
Throws: - IllegalArgumentException – if the given
implementation is null.
- NotCompliantMBeanException – if the mbeanInterface
does not follow JMX design patterns for Management Interfaces, or
if the given implementation does not implement the
specified interface.
/**
* <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);
}
Make a DynamicMBean out of this, using the specified
mbeanInterface class.
Call
this(this,mbeanInterface)
. This constructor is reserved to subclasses.
Params: - mbeanInterface – The Management Interface exported by this
MBean.
Throws: - NotCompliantMBeanException – if the mbeanInterface
does not follow JMX design patterns for Management Interfaces, or
if this does not implement the specified interface.
/**
* <p>Make a DynamicMBean out of <var>this</var>, using the specified
* <var>mbeanInterface</var> class.</p>
*
* <p>Call {@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);
}
Make a DynamicMBean out of the object
implementation, using the specified
mbeanInterface class. This constructor can be used to make either Standard MBeans or MXBeans. Unlike the constructor StandardMBean(Object, Class<Object>)
, it does not throw NotCompliantMBeanException.
Params: - implementation – The implementation of this MBean.
- mbeanInterface – The Management Interface exported by this
MBean's implementation. If
null
, then this
object will use standard JMX design pattern to determine
the management interface associated with the given
implementation. - isMXBean – If true, the
mbeanInterface
parameter names an MXBean interface and the resultant MBean is an MXBean.
Type parameters: - <T> – Allows the compiler to check that
implementation
does indeed implement the class described by mbeanInterface
. The compiler can only check this if mbeanInterface
is a class literal such as MyMBean.class
.
Throws: - IllegalArgumentException – if the given
implementation is null, or if the mbeanInterface
does not follow JMX design patterns for Management Interfaces, or
if the given implementation does not implement the
specified interface.
Since: 1.6
/**
* <p>Make a DynamicMBean out of the object
* <var>implementation</var>, using the specified
* <var>mbeanInterface</var> class. 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);
}
}
Make a DynamicMBean out of this, using the specified
mbeanInterface class. This constructor can be used to make either Standard MBeans or MXBeans. Unlike the constructor StandardMBean(Object, Class<Object>)
, it does not throw NotCompliantMBeanException.
Call
this(this, mbeanInterface, isMXBean)
. This constructor is reserved to subclasses.
Params: - mbeanInterface – The Management Interface exported by this
MBean.
- isMXBean – If true, the
mbeanInterface
parameter names an MXBean interface and the resultant MBean is an MXBean.
Throws: - IllegalArgumentException – if the mbeanInterface
does not follow JMX design patterns for Management Interfaces, or
if this does not implement the specified interface.
Since: 1.6
/**
* <p>Make a DynamicMBean out of <var>this</var>, using the specified
* <var>mbeanInterface</var> class. 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>Call {@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);
}
}
Replace the implementation object wrapped in this object.
Params: - implementation – The new implementation of this Standard MBean
(or MXBean). The
implementation
object must implement
the Standard MBean (or MXBean) interface that was supplied when this
StandardMBean
was constructed.
Throws: - IllegalArgumentException – if the given
implementation is null.
- NotCompliantMBeanException – if the given
implementation does not implement the
Standard MBean (or MXBean) interface that was
supplied at construction.
See Also:
/**
* <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).
See Also: Returns: The implementation of this Standard MBean (or MXBean).
/**
* 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).
Returns: The management interface of this Standard MBean (or MXBean).
/**
* 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).
Returns: The class of the implementation of this Standard MBean (or MXBean).
/**
* 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 MBeanInfo
for this MBean. This method implements
DynamicMBean.getMBeanInfo()
.
This method first calls getCachedMBeanInfo()
in order to retrieve the cached MBeanInfo for this MBean, if any. If the MBeanInfo returned by getCachedMBeanInfo()
is not null, then it is returned.
Otherwise, this method builds a default MBeanInfo for this MBean,
using the Management Interface specified for this MBean.
While building the MBeanInfo, this method calls the customization
hooks that make it possible for subclasses to supply their custom
descriptions, parameter names, etc...
Finally, it calls
cacheMBeanInfo()
in order to cache the new MBeanInfo.
Returns: The cached MBeanInfo for that MBean, if not null, or a
newly built MBeanInfo if none was cached.
/**
* 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.
Subclasses may redefine this method in order to supply their custom class name. The default implementation returns info.getClassName()
. Params: - info – The default MBeanInfo derived by reflection.
Returns: the class name for the new MBeanInfo.
/**
* 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.
Subclasses may redefine this method in order to supply their custom MBean description. The default implementation returns info.getDescription()
. Params: - info – The default MBeanInfo derived by reflection.
Returns: the description for the new MBeanInfo.
/**
* 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
* {@link MBeanInfo#getDescription() info.getDescription()}.
* @param info The default MBeanInfo derived by reflection.
* @return the description for the new MBeanInfo.
**/
protected String getDescription(MBeanInfo info) {
if (info == null) return null;
return info.getDescription();
}
Customization hook:
Get the description that will be used in the MBeanFeatureInfo
returned by this MBean.
Subclasses may redefine this method in order to supply their custom description. The default implementation returns
info.getDescription()
.
This method is called by getDescription(MBeanAttributeInfo)
, getDescription(MBeanOperationInfo)
, getDescription(MBeanConstructorInfo)
.
Params: - info – The default MBeanFeatureInfo derived by reflection.
Returns: the description for the given MBeanFeatureInfo.
/**
* <p>Customization hook:
* Get the description that will be used in the MBeanFeatureInfo
* returned by this MBean.</p>
*
* <p>Subclasses may redefine this method in order to supply
* their custom description. The default implementation returns
* {@link MBeanFeatureInfo#getDescription()
* info.getDescription()}.</p>
*
* <p>This method is called by
* {@link #getDescription(MBeanAttributeInfo)},
* {@link #getDescription(MBeanOperationInfo)},
* {@link #getDescription(MBeanConstructorInfo)}.</p>
*
* @param info The default MBeanFeatureInfo derived by reflection.
* @return the description for the given MBeanFeatureInfo.
**/
protected String getDescription(MBeanFeatureInfo info) {
if (info == null) return null;
return info.getDescription();
}
Customization hook:
Get the description that will be used in the MBeanAttributeInfo
returned by this MBean.
Subclasses may redefine this method in order to supply their custom description. The default implementation returns
getDescription((MBeanFeatureInfo) info)
.
Params: - info – The default MBeanAttributeInfo derived by reflection.
Returns: the description for the given MBeanAttributeInfo.
/**
* Customization hook:
* Get the description that will be used in the MBeanAttributeInfo
* returned by this MBean.
*
* <p>Subclasses may redefine this method in order to supply their
* custom description. The default implementation returns {@link
* #getDescription(MBeanFeatureInfo)
* getDescription((MBeanFeatureInfo) info)}.
* @param info The default MBeanAttributeInfo derived by reflection.
* @return the description for the given MBeanAttributeInfo.
**/
protected String getDescription(MBeanAttributeInfo info) {
return getDescription((MBeanFeatureInfo)info);
}
Customization hook:
Get the description that will be used in the MBeanConstructorInfo
returned by this MBean.
Subclasses may redefine this method in order to supply their custom description. The default implementation returns
getDescription((MBeanFeatureInfo) info)
. Params: - info – The default MBeanConstructorInfo derived by reflection.
Returns: the description for the given MBeanConstructorInfo.
/**
* Customization hook:
* Get the description that will be used in the MBeanConstructorInfo
* returned by this MBean.
* <br>
* Subclasses may redefine this method in order to supply their
* custom description.
* The default implementation returns {@link
* #getDescription(MBeanFeatureInfo)
* getDescription((MBeanFeatureInfo) info)}.
* @param info The default MBeanConstructorInfo derived by reflection.
* @return the description for the given MBeanConstructorInfo.
**/
protected String getDescription(MBeanConstructorInfo info) {
return getDescription((MBeanFeatureInfo)info);
}
Customization hook:
Get the description that will be used for the sequence
MBeanParameterInfo of the MBeanConstructorInfo returned by this MBean.
Subclasses may redefine this method in order to supply their custom description. The default implementation returns param.getDescription()
. Params: - ctor – The default MBeanConstructorInfo derived by reflection.
- param – The default MBeanParameterInfo derived by reflection.
- sequence – The sequence number of the parameter considered
("0" for the first parameter, "1" for the second parameter,
etc...).
Returns: the description for the given MBeanParameterInfo.
/**
* Customization hook:
* Get the description that will be used for the <var>sequence</var>
* MBeanParameterInfo of the MBeanConstructorInfo returned by this MBean.
* <br>
* Subclasses may redefine this method in order to supply their
* custom description. The default implementation returns
* {@link MBeanParameterInfo#getDescription() param.getDescription()}.
*
* @param ctor The default MBeanConstructorInfo derived by reflection.
* @param param The default MBeanParameterInfo derived by reflection.
* @param sequence The sequence number of the parameter considered
* ("0" for the first parameter, "1" for the second parameter,
* etc...).
* @return the description for the given MBeanParameterInfo.
**/
protected String getDescription(MBeanConstructorInfo ctor,
MBeanParameterInfo param,
int sequence) {
if (param == null) return null;
return param.getDescription();
}
Customization hook:
Get the name that will be used for the sequence
MBeanParameterInfo of the MBeanConstructorInfo returned by this MBean.
Subclasses may redefine this method in order to supply their custom parameter name. The default implementation returns param.getName()
. Params: - ctor – The default MBeanConstructorInfo derived by reflection.
- param – The default MBeanParameterInfo derived by reflection.
- sequence – The sequence number of the parameter considered
("0" for the first parameter, "1" for the second parameter,
etc...).
Returns: the name for the given MBeanParameterInfo.
/**
* Customization hook:
* Get the name that will be used for the <var>sequence</var>
* MBeanParameterInfo of the MBeanConstructorInfo returned by this MBean.
* <br>
* Subclasses may redefine this method in order to supply their
* custom parameter name. The default implementation returns
* {@link MBeanParameterInfo#getName() param.getName()}.
*
* @param ctor The default MBeanConstructorInfo derived by reflection.
* @param param The default MBeanParameterInfo derived by reflection.
* @param sequence The sequence number of the parameter considered
* ("0" for the first parameter, "1" for the second parameter,
* etc...).
* @return the name for the given MBeanParameterInfo.
**/
protected String getParameterName(MBeanConstructorInfo ctor,
MBeanParameterInfo param,
int sequence) {
if (param == null) return null;
return param.getName();
}
Customization hook:
Get the description that will be used in the MBeanOperationInfo
returned by this MBean.
Subclasses may redefine this method in order to supply their custom description. The default implementation returns
getDescription((MBeanFeatureInfo) info)
. Params: - info – The default MBeanOperationInfo derived by reflection.
Returns: the description for the given MBeanOperationInfo.
/**
* Customization hook:
* Get the description that will be used in the MBeanOperationInfo
* returned by this MBean.
* <br>
* Subclasses may redefine this method in order to supply their
* custom description. The default implementation returns
* {@link #getDescription(MBeanFeatureInfo)
* getDescription((MBeanFeatureInfo) info)}.
* @param info The default MBeanOperationInfo derived by reflection.
* @return the description for the given MBeanOperationInfo.
**/
protected String getDescription(MBeanOperationInfo info) {
return getDescription((MBeanFeatureInfo)info);
}
Customization hook:
Get the impact flag of the operation that will be used in
the MBeanOperationInfo returned by this MBean.
Subclasses may redefine this method in order to supply their custom impact flag. The default implementation returns info.getImpact()
. Params: - info – The default MBeanOperationInfo derived by reflection.
Returns: the impact flag for the given MBeanOperationInfo.
/**
* Customization hook:
* Get the <var>impact</var> flag of the operation that will be used in
* the MBeanOperationInfo returned by this MBean.
* <br>
* Subclasses may redefine this method in order to supply their
* custom impact flag. The default implementation returns
* {@link MBeanOperationInfo#getImpact() info.getImpact()}.
* @param info The default MBeanOperationInfo derived by reflection.
* @return the impact flag for the given MBeanOperationInfo.
**/
protected int getImpact(MBeanOperationInfo info) {
if (info == null) return MBeanOperationInfo.UNKNOWN;
return info.getImpact();
}
Customization hook:
Get the name that will be used for the sequence
MBeanParameterInfo of the MBeanOperationInfo returned by this MBean.
Subclasses may redefine this method in order to supply their custom parameter name. The default implementation returns param.getName()
. Params: - op – The default MBeanOperationInfo derived by reflection.
- param – The default MBeanParameterInfo derived by reflection.
- sequence – The sequence number of the parameter considered
("0" for the first parameter, "1" for the second parameter,
etc...).
Returns: the name to use for the given MBeanParameterInfo.
/**
* Customization hook:
* Get the name that will be used for the <var>sequence</var>
* MBeanParameterInfo of the MBeanOperationInfo returned by this MBean.
* <br>
* Subclasses may redefine this method in order to supply their
* custom parameter name. The default implementation returns
* {@link MBeanParameterInfo#getName() param.getName()}.
*
* @param op The default MBeanOperationInfo derived by reflection.
* @param param The default MBeanParameterInfo derived by reflection.
* @param sequence The sequence number of the parameter considered
* ("0" for the first parameter, "1" for the second parameter,
* etc...).
* @return the name to use for the given MBeanParameterInfo.
**/
protected String getParameterName(MBeanOperationInfo op,
MBeanParameterInfo param,
int sequence) {
if (param == null) return null;
return param.getName();
}
Customization hook:
Get the description that will be used for the sequence
MBeanParameterInfo of the MBeanOperationInfo returned by this MBean.
Subclasses may redefine this method in order to supply their custom description. The default implementation returns param.getDescription()
. Params: - op – The default MBeanOperationInfo derived by reflection.
- param – The default MBeanParameterInfo derived by reflection.
- sequence – The sequence number of the parameter considered
("0" for the first parameter, "1" for the second parameter,
etc...).
Returns: the description for the given MBeanParameterInfo.
/**
* Customization hook:
* Get the description that will be used for the <var>sequence</var>
* MBeanParameterInfo of the MBeanOperationInfo returned by this MBean.
* <br>
* Subclasses may redefine this method in order to supply their
* custom description. The default implementation returns
* {@link MBeanParameterInfo#getDescription() param.getDescription()}.
*
* @param op The default MBeanOperationInfo derived by reflection.
* @param param The default MBeanParameterInfo derived by reflection.
* @param sequence The sequence number of the parameter considered
* ("0" for the first parameter, "1" for the second parameter,
* etc...).
* @return the description for the given MBeanParameterInfo.
**/
protected String getDescription(MBeanOperationInfo op,
MBeanParameterInfo param,
int sequence) {
if (param == null) return null;
return param.getDescription();
}
Customization hook:
Get the MBeanConstructorInfo[] that will be used in the MBeanInfo
returned by this MBean.
By default, this method returns null
if the wrapped
implementation is not this. Indeed, if the wrapped
implementation is not this object itself, it will not be possible
to recreate a wrapped implementation by calling the implementation
constructors through MBeanServer.createMBean(...)
.
Otherwise, if the wrapped implementation is this,
ctors is returned.
Subclasses may redefine this method in order to modify this
behavior, if needed.
Params: - ctors – The default MBeanConstructorInfo[] derived by reflection.
- impl – The wrapped implementation. If
null
is
passed, the wrapped implementation is ignored and
ctors is returned.
Returns: the MBeanConstructorInfo[] for the new MBeanInfo.
/**
* Customization hook:
* Get the MBeanConstructorInfo[] that will be used in the MBeanInfo
* returned by this MBean.
* <br>
* By default, this method returns <code>null</code> if the wrapped
* implementation is not <var>this</var>. Indeed, if the wrapped
* implementation is not this object itself, it will not be possible
* to recreate a wrapped implementation by calling the implementation
* constructors through <code>MBeanServer.createMBean(...)</code>.<br>
* Otherwise, if the wrapped implementation is <var>this</var>,
* <var>ctors</var> is returned.
* <br>
* Subclasses may redefine this method in order to modify this
* behavior, if needed.
* @param ctors The default MBeanConstructorInfo[] derived by reflection.
* @param impl The wrapped implementation. If <code>null</code> is
* passed, the wrapped implementation is ignored and
* <var>ctors</var> is returned.
* @return the MBeanConstructorInfo[] for the new MBeanInfo.
**/
protected MBeanConstructorInfo[]
getConstructors(MBeanConstructorInfo[] ctors, Object impl) {
if (ctors == null) return null;
if (impl != null && impl != this) return null;
return ctors;
}
Customization hook:
Get the MBeanNotificationInfo[] that will be used in the MBeanInfo
returned by this MBean.
Subclasses may redefine this method in order to supply their
custom notifications.
Params: - info – The default MBeanInfo derived by reflection.
Returns: the MBeanNotificationInfo[] for the new MBeanInfo.
/**
* Customization hook:
* Get the MBeanNotificationInfo[] that will be used in the MBeanInfo
* returned by this MBean.
* <br>
* Subclasses may redefine this method in order to supply their
* custom notifications.
* @param info The default MBeanInfo derived by reflection.
* @return the MBeanNotificationInfo[] for the new MBeanInfo.
**/
MBeanNotificationInfo[] getNotifications(MBeanInfo info) {
return null;
}
Get the Descriptor that will be used in the MBeanInfo
returned by this MBean.
Subclasses may redefine this method in order to supply
their custom descriptor.
The default implementation of this method returns a Descriptor that contains at least the field interfaceClassName
, with value getMBeanInterface()
.getName(). It may also contain the field immutableInfo
, with a value that is the string "true"
if the implementation can determine that the MBeanInfo
returned by getMBeanInfo()
will always be the same. It may contain other fields: fields defined by the JMX specification must have appropriate values, and other fields must follow the conventions for non-standard field names.
Params: - info – The default MBeanInfo derived by reflection.
Returns: the Descriptor for the new MBeanInfo.
/**
* <p>Get the Descriptor that will be used in the MBeanInfo
* returned by this MBean.</p>
*
* <p>Subclasses may redefine this method in order to supply
* their custom descriptor.</p>
*
* <p>The default implementation of this method returns a Descriptor
* that contains at least the field {@code interfaceClassName}, with
* value {@link #getMBeanInterface()}.getName(). It may also contain
* the field {@code immutableInfo}, with a value that is the string
* {@code "true"} if the implementation can determine that the
* {@code MBeanInfo} returned by {@link #getMBeanInfo()} will always
* be the same. It may contain other fields: fields defined by the
* JMX specification must have appropriate values, and other fields
* must follow the conventions for non-standard field names.</p>
*
* @param info The default MBeanInfo derived by reflection.
* @return the Descriptor for the new MBeanInfo.
*/
Descriptor getDescriptor(MBeanInfo info, boolean immutableInfo) {
ImmutableDescriptor desc = null;
if (info == null ||
info.getDescriptor() == null ||
info.getDescriptor().getFieldNames().length == 0) {
final String interfaceClassNameS =
"interfaceClassName=" + getMBeanInterface().getName();
final String immutableInfoS =
"immutableInfo=" + immutableInfo;
desc = new ImmutableDescriptor(interfaceClassNameS, immutableInfoS);
desc = descriptors.get(desc);
} else {
Descriptor d = info.getDescriptor();
Map<String,Object> fields = new HashMap<String,Object>();
for (String fieldName : d.getFieldNames()) {
if (fieldName.equals("immutableInfo")) {
// Replace immutableInfo as the underlying MBean/MXBean
// could already implement NotificationBroadcaster and
// return immutableInfo=true in its MBeanInfo.
fields.put(fieldName, Boolean.toString(immutableInfo));
} else {
fields.put(fieldName, d.getFieldValue(fieldName));
}
}
desc = new ImmutableDescriptor(fields);
}
return desc;
}
Customization hook:
Return the MBeanInfo cached for this object.
Subclasses may redefine this method in order to implement their own caching policy. The default implementation stores one MBeanInfo
object per instance.
See Also: Returns: The cached MBeanInfo, or null if no MBeanInfo is cached.
/**
* Customization hook:
* Return the MBeanInfo cached for this object.
*
* <p>Subclasses may redefine this method in order to implement their
* own caching policy. The default implementation stores one
* {@link MBeanInfo} object per instance.
*
* @return The cached MBeanInfo, or null if no MBeanInfo is cached.
*
* @see #cacheMBeanInfo(MBeanInfo)
**/
protected MBeanInfo getCachedMBeanInfo() {
return cachedMBeanInfo;
}
Customization hook:
cache the MBeanInfo built for this object.
Subclasses may redefine this method in order to implement
their own caching policy. The default implementation stores
info
in this instance. A subclass can define
other policies, such as not saving info
(so it is reconstructed every time getMBeanInfo()
is called) or sharing a unique MBeanInfo
object when several StandardMBean
instances have equal MBeanInfo
values.
Params: - info – the new
MBeanInfo
to cache. Any
previously cached value is discarded. This parameter may be
null, in which case there is no new cached value.
/**
* Customization hook:
* cache the MBeanInfo built for this object.
*
* <p>Subclasses may redefine this method in order to implement
* their own caching policy. The default implementation stores
* <code>info</code> in this instance. A subclass can define
* other policies, such as not saving <code>info</code> (so it is
* reconstructed every time {@link #getMBeanInfo()} is called) or
* sharing a unique {@link MBeanInfo} object when several
* <code>StandardMBean</code> instances have equal {@link
* MBeanInfo} values.
*
* @param info the new <code>MBeanInfo</code> to cache. Any
* previously cached value is discarded. This parameter may be
* null, in which case there is no new cached value.
**/
protected void cacheMBeanInfo(MBeanInfo info) {
cachedMBeanInfo = info;
}
private boolean isMXBean() {
return mbean.isMXBean();
}
private static <T> boolean identicalArrays(T[] a, T[] b) {
if (a == b)
return true;
if (a == null || b == null || a.length != b.length)
return false;
for (int i = 0; i < a.length; i++) {
if (a[i] != b[i])
return false;
}
return true;
}
private static <T> boolean equal(T a, T b) {
if (a == b)
return true;
if (a == null || b == null)
return false;
return a.equals(b);
}
private static MBeanParameterInfo
customize(MBeanParameterInfo pi,
String name,
String description) {
if (equal(name, pi.getName()) &&
equal(description, pi.getDescription()))
return pi;
else if (pi instanceof OpenMBeanParameterInfo) {
OpenMBeanParameterInfo opi = (OpenMBeanParameterInfo) pi;
return new OpenMBeanParameterInfoSupport(name,
description,
opi.getOpenType(),
pi.getDescriptor());
} else {
return new MBeanParameterInfo(name,
pi.getType(),
description,
pi.getDescriptor());
}
}
private static MBeanConstructorInfo
customize(MBeanConstructorInfo ci,
String description,
MBeanParameterInfo[] signature) {
if (equal(description, ci.getDescription()) &&
identicalArrays(signature, ci.getSignature()))
return ci;
if (ci instanceof OpenMBeanConstructorInfo) {
OpenMBeanParameterInfo[] oparams =
paramsToOpenParams(signature);
return new OpenMBeanConstructorInfoSupport(ci.getName(),
description,
oparams,
ci.getDescriptor());
} else {
return new MBeanConstructorInfo(ci.getName(),
description,
signature,
ci.getDescriptor());
}
}
private static MBeanOperationInfo
customize(MBeanOperationInfo oi,
String description,
MBeanParameterInfo[] signature,
int impact) {
if (equal(description, oi.getDescription()) &&
identicalArrays(signature, oi.getSignature()) &&
impact == oi.getImpact())
return oi;
if (oi instanceof OpenMBeanOperationInfo) {
OpenMBeanOperationInfo ooi = (OpenMBeanOperationInfo) oi;
OpenMBeanParameterInfo[] oparams =
paramsToOpenParams(signature);
return new OpenMBeanOperationInfoSupport(oi.getName(),
description,
oparams,
ooi.getReturnOpenType(),
impact,
oi.getDescriptor());
} else {
return new MBeanOperationInfo(oi.getName(),
description,
signature,
oi.getReturnType(),
impact,
oi.getDescriptor());
}
}
private static MBeanAttributeInfo
customize(MBeanAttributeInfo ai,
String description) {
if (equal(description, ai.getDescription()))
return ai;
if (ai instanceof OpenMBeanAttributeInfo) {
OpenMBeanAttributeInfo oai = (OpenMBeanAttributeInfo) ai;
return new OpenMBeanAttributeInfoSupport(ai.getName(),
description,
oai.getOpenType(),
ai.isReadable(),
ai.isWritable(),
ai.isIs(),
ai.getDescriptor());
} else {
return new MBeanAttributeInfo(ai.getName(),
ai.getType(),
description,
ai.isReadable(),
ai.isWritable(),
ai.isIs(),
ai.getDescriptor());
}
}
private static OpenMBeanParameterInfo[]
paramsToOpenParams(MBeanParameterInfo[] params) {
if (params instanceof OpenMBeanParameterInfo[])
return (OpenMBeanParameterInfo[]) params;
OpenMBeanParameterInfo[] oparams =
new OpenMBeanParameterInfoSupport[params.length];
System.arraycopy(params, 0, oparams, 0, params.length);
return oparams;
}
// ------------------------------------------------------------------
// Build the custom MBeanConstructorInfo[]
// ------------------------------------------------------------------
private MBeanConstructorInfo[]
getConstructors(MBeanInfo info, Object impl) {
final MBeanConstructorInfo[] ctors =
getConstructors(info.getConstructors(), impl);
if (ctors == null)
return null;
final int ctorlen = ctors.length;
final MBeanConstructorInfo[] nctors = new MBeanConstructorInfo[ctorlen];
for (int i=0; i<ctorlen; i++) {
final MBeanConstructorInfo c = ctors[i];
final MBeanParameterInfo[] params = c.getSignature();
final MBeanParameterInfo[] nps;
if (params != null) {
final int plen = params.length;
nps = new MBeanParameterInfo[plen];
for (int ii=0;ii<plen;ii++) {
MBeanParameterInfo p = params[ii];
nps[ii] = customize(p,
getParameterName(c,p,ii),
getDescription(c,p,ii));
}
} else {
nps = null;
}
nctors[i] =
customize(c, getDescription(c), nps);
}
return nctors;
}
// ------------------------------------------------------------------
// Build the custom MBeanOperationInfo[]
// ------------------------------------------------------------------
private MBeanOperationInfo[] getOperations(MBeanInfo info) {
final MBeanOperationInfo[] ops = info.getOperations();
if (ops == null)
return null;
final int oplen = ops.length;
final MBeanOperationInfo[] nops = new MBeanOperationInfo[oplen];
for (int i=0; i<oplen; i++) {
final MBeanOperationInfo o = ops[i];
final MBeanParameterInfo[] params = o.getSignature();
final MBeanParameterInfo[] nps;
if (params != null) {
final int plen = params.length;
nps = new MBeanParameterInfo[plen];
for (int ii=0;ii<plen;ii++) {
MBeanParameterInfo p = params[ii];
nps[ii] = customize(p,
getParameterName(o,p,ii),
getDescription(o,p,ii));
}
} else {
nps = null;
}
nops[i] = customize(o, getDescription(o), nps, getImpact(o));
}
return nops;
}
// ------------------------------------------------------------------
// Build the custom MBeanAttributeInfo[]
// ------------------------------------------------------------------
private MBeanAttributeInfo[] getAttributes(MBeanInfo info) {
final MBeanAttributeInfo[] atts = info.getAttributes();
if (atts == null)
return null; // should not happen
final MBeanAttributeInfo[] natts;
final int attlen = atts.length;
natts = new MBeanAttributeInfo[attlen];
for (int i=0; i<attlen; i++) {
final MBeanAttributeInfo a = atts[i];
natts[i] = customize(a, getDescription(a));
}
return natts;
}
Allows the MBean to perform any operations it needs before
being registered in the MBean server. If the name of the MBean
is not specified, the MBean can provide a name for its
registration. If any exception is raised, the MBean will not be
registered in the MBean server.
The default implementation of this method returns the name
parameter. It does nothing else for Standard MBeans. For MXBeans, it records the MBeanServer
and ObjectName
parameters so they can be used to translate inter-MXBean references.
It is good practice for a subclass that overrides this method to call the overridden method via super.preRegister(...)
. This is necessary if this object is an MXBean that is referenced by attributes or operations in other MXBeans.
Params: - server – The MBean server in which the MBean will be registered.
- name – The object name of the MBean. This name is null if
the name parameter to one of the
createMBean
or
registerMBean
methods in the MBeanServer
interface is null. In that case, this method must return a non-null ObjectName for the new MBean.
Throws: - IllegalArgumentException – if this is an MXBean and
name
is null. - InstanceAlreadyExistsException – if this is an MXBean and
it has already been registered under another name (in this
MBean Server or another).
- Exception – no other checked exceptions are thrown by this method but
Exception
is declared so that subclasses can override the method and throw their own exceptions.
Returns: The name under which the MBean is to be registered.
This value must not be null. If the name
parameter is not null, it will usually but not necessarily be
the returned value. Since: 1.6
/**
* <p>Allows the MBean to perform any operations it needs before
* being registered in the MBean server. If the name of the MBean
* is not specified, the MBean can provide a name for its
* registration. If any exception is raised, the MBean will not be
* registered in the MBean server.</p>
*
* <p>The default implementation of this method returns the {@code name}
* parameter. It does nothing else for
* Standard MBeans. For MXBeans, it records the {@code MBeanServer}
* and {@code ObjectName} parameters so they can be used to translate
* inter-MXBean references.</p>
*
* <p>It is good practice for a subclass that overrides this method
* to call the overridden method via {@code super.preRegister(...)}.
* This is necessary if this object is an MXBean that is referenced
* by attributes or operations in other MXBeans.</p>
*
* @param server The MBean server in which the MBean will be registered.
*
* @param name The object name of the MBean. This name is null if
* the name parameter to one of the <code>createMBean</code> or
* <code>registerMBean</code> methods in the {@link MBeanServer}
* interface is null. In that case, this method must return a
* non-null ObjectName for the new MBean.
*
* @return The name under which the MBean is to be registered.
* This value must not be null. If the <code>name</code>
* parameter is not null, it will usually but not necessarily be
* the returned value.
*
* @throws IllegalArgumentException if this is an MXBean and
* {@code name} is null.
*
* @throws InstanceAlreadyExistsException if this is an MXBean and
* it has already been registered under another name (in this
* MBean Server or another).
*
* @throws Exception no other checked exceptions are thrown by
* this method but {@code Exception} is declared so that subclasses
* can override the method and throw their own exceptions.
*
* @since 1.6
*/
public ObjectName preRegister(MBeanServer server, ObjectName name)
throws Exception {
mbean.register(server, name);
return name;
}
Allows the MBean to perform any operations needed after having been
registered in the MBean server or after the registration has failed.
The default implementation of this method does nothing for Standard MBeans. For MXBeans, it undoes any work done by preRegister
if registration fails.
It is good practice for a subclass that overrides this method to call the overridden method via super.postRegister(...)
. This is necessary if this object is an MXBean that is referenced by attributes or operations in other MXBeans.
Params: - registrationDone – Indicates whether or not the MBean has
been successfully registered in the MBean server. The value
false means that the registration phase has failed.
Since: 1.6
/**
* <p>Allows the MBean to perform any operations needed after having been
* registered in the MBean server or after the registration has failed.</p>
*
* <p>The default implementation of this method does nothing for
* Standard MBeans. For MXBeans, it undoes any work done by
* {@link #preRegister preRegister} if registration fails.</p>
*
* <p>It is good practice for a subclass that overrides this method
* to call the overridden method via {@code super.postRegister(...)}.
* This is necessary if this object is an MXBean that is referenced
* by attributes or operations in other MXBeans.</p>
*
* @param registrationDone Indicates whether or not the MBean has
* been successfully registered in the MBean server. The value
* false means that the registration phase has failed.
*
* @since 1.6
*/
public void postRegister(Boolean registrationDone) {
if (!registrationDone)
mbean.unregister();
}
Allows the MBean to perform any operations it needs before
being unregistered by the MBean server.
The default implementation of this method does nothing.
It is good practice for a subclass that overrides this method to call the overridden method via super.preDeegister(...)
.
Throws: - Exception – no checked exceptions are throw by this method but
Exception
is declared so that subclasses can override this method and throw their own exceptions.
Since: 1.6
/**
* <p>Allows the MBean to perform any operations it needs before
* being unregistered by the MBean server.</p>
*
* <p>The default implementation of this method does nothing.</p>
*
* <p>It is good practice for a subclass that overrides this method
* to call the overridden method via {@code super.preDeegister(...)}.</p>
*
* @throws Exception no checked exceptions are throw by this method
* but {@code Exception} is declared so that subclasses can override
* this method and throw their own exceptions.
*
* @since 1.6
*/
public void preDeregister() throws Exception {
}
Allows the MBean to perform any operations needed after having been
unregistered in the MBean server.
The default implementation of this method does nothing for Standard MBeans. For MXBeans, it removes any information that was recorded by the preRegister
method.
It is good practice for a subclass that overrides this method to call the overridden method via super.postRegister(...)
. This is necessary if this object is an MXBean that is referenced by attributes or operations in other MXBeans.
Since: 1.6
/**
* <p>Allows the MBean to perform any operations needed after having been
* unregistered in the MBean server.</p>
*
* <p>The default implementation of this method does nothing for
* Standard MBeans. For MXBeans, it removes any information that
* was recorded by the {@link #preRegister preRegister} method.</p>
*
* <p>It is good practice for a subclass that overrides this method
* to call the overridden method via {@code super.postRegister(...)}.
* This is necessary if this object is an MXBean that is referenced
* by attributes or operations in other MXBeans.</p>
*
* @since 1.6
*/
public void postDeregister() {
mbean.unregister();
}
//
// MBeanInfo immutability
//
Cached results of previous calls to immutableInfo. This is
a WeakHashMap so that we don't prevent a class from being
garbage collected just because we know whether its MBeanInfo
is immutable.
/**
* Cached results of previous calls to immutableInfo. This is
* a WeakHashMap so that we don't prevent a class from being
* garbage collected just because we know whether its MBeanInfo
* is immutable.
*/
private static final Map<Class, Boolean> mbeanInfoSafeMap =
new WeakHashMap<Class, Boolean>();
Return true if subclass
is known to preserve the immutability of the MBeanInfo
. The subclass
is considered to have an immutable MBeanInfo
if it does not override any of the getMBeanInfo, getCachedMBeanInfo, cacheMBeanInfo and getNotificationInfo methods. /**
* Return true if {@code subclass} is known to preserve the immutability
* of the {@code MBeanInfo}. The {@code subclass} is considered to have
* an immutable {@code MBeanInfo} if it does not override any of the
* getMBeanInfo, getCachedMBeanInfo, cacheMBeanInfo and getNotificationInfo
* methods.
*/
static boolean immutableInfo(Class<? extends StandardMBean> subclass) {
if (subclass == StandardMBean.class ||
subclass == StandardEmitterMBean.class)
return true;
synchronized (mbeanInfoSafeMap) {
Boolean safe = mbeanInfoSafeMap.get(subclass);
if (safe == null) {
try {
MBeanInfoSafeAction action =
new MBeanInfoSafeAction(subclass);
safe = AccessController.doPrivileged(action);
} catch (Exception e) { // e.g. SecurityException
/* We don't know, so we assume it isn't. */
safe = false;
}
mbeanInfoSafeMap.put(subclass, safe);
}
return safe;
}
}
static boolean overrides(Class<?> subclass, Class<?> superclass,
String name, Class<?>... params) {
for (Class<?> c = subclass; c != superclass; c = c.getSuperclass()) {
try {
c.getDeclaredMethod(name, params);
return true;
} catch (NoSuchMethodException e) {
// OK: this class doesn't override it
}
}
return false;
}
private static class MBeanInfoSafeAction
implements PrivilegedAction<Boolean> {
private final Class subclass;
MBeanInfoSafeAction(Class subclass) {
this.subclass = subclass;
}
public Boolean run() {
// Check for "void cacheMBeanInfo(MBeanInfo)" method.
//
if (overrides(subclass, StandardMBean.class,
"cacheMBeanInfo", MBeanInfo.class))
return false;
// Check for "MBeanInfo getCachedMBeanInfo()" method.
//
if (overrides(subclass, StandardMBean.class,
"getCachedMBeanInfo", (Class[]) null))
return false;
// Check for "MBeanInfo getMBeanInfo()" method.
//
if (overrides(subclass, StandardMBean.class,
"getMBeanInfo", (Class[]) null))
return false;
// Check for "MBeanNotificationInfo[] getNotificationInfo()"
// method.
//
// This method is only taken into account for the MBeanInfo
// immutability checks if and only if the given subclass is
// StandardEmitterMBean itself or can be assigned to
// StandardEmitterMBean.
//
if (StandardEmitterMBean.class.isAssignableFrom(subclass))
if (overrides(subclass, StandardEmitterMBean.class,
"getNotificationInfo", (Class[]) null))
return false;
return true;
}
}
}