FileDocCategorySizeDatePackage
StandardMBean.javaAPI DocJava SE 5 API31506Fri Aug 26 14:57:34 BST 2005javax.management

StandardMBean

public class StandardMBean extends Object implements DynamicMBean

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 {@link 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 {@link #StandardMBean(java.lang.Object, java.lang.Class) StandardMBean(impl,interface)}:
    MBeanServer mbs;
    ...
    Impl impl = new Impl(...);
    StandardMBean mbean = new StandardMBean(impl, Intf.class);
    mbs.registerMBean(mbean, objectName);
    
  • Subclassing StandardMBean:
    public class Impl extends StandardMBean implements Intf {
    public Impl() {
    super(Intf.class);
    }
    // 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.

since
1.5
since.unbundled
JMX 1.2

Fields Summary
private static final String
dbgTag
The name of this class to be used for tracing
private Class
mbeanInterface
The management interface.
private Object
implementation
The implementation.
private final com.sun.jmx.mbeanserver.StandardMBeanMetaDataImpl
meta
The MetaData object used for invoking reflection.
private MBeanInfo
cachedMBeanInfo
The cached MBeanInfo.
Constructors Summary
private StandardMBean(Object implementation, Class mbeanInterface, boolean nullImplementationAllowed)
Make a DynamicMBean out of implementation, using the specified mbeanInterface class.

param
implementation The implementation of this MBean. If null, and null implementation is allowed, then the implementation is assumed to be this.
param
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.
param
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.
exception
IllegalArgumentException if the given implementation is null, and null is not allowed.
exception
NotCompliantMBeanException if the mbeanInterface does not follow JMX design patterns for Management Interfaces, or if the given implementation does not implement the specified interface.


                                                                                                                                                                                                                            
        
			    
	  
	if (implementation == null) {
	    if (nullImplementationAllowed) implementation = this;
	    else throw new IllegalArgumentException("implementation is null");
	}
	this.meta = new StandardMBeanMetaDataImpl(this);
	setImplementation(implementation,mbeanInterface);
    
public StandardMBean(Object implementation, Class mbeanInterface)

Make a DynamicMBean out of the object implementation, using the specified mbeanInterface class.

param
implementation The implementation of this MBean.
param
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.
exception
IllegalArgumentException if the given implementation is null.
exception
NotCompliantMBeanException if the mbeanInterface does not follow JMX design patterns for Management Interfaces, or if the given implementation does not implement the specified interface.

	this(implementation,mbeanInterface,false);
    
protected StandardMBean(Class mbeanInterface)

Make a DynamicMBean out of this, using the specified mbeanInterface class.

Call {@link #StandardMBean(java.lang.Object, java.lang.Class) this(this,mbeanInterface)}. This constructor is reserved to subclasses.

param
mbeanInterface The Management Interface exported by this MBean.
exception
NotCompliantMBeanException if the mbeanInterface does not follow JMX design patterns for Management Interfaces, or if this does not implement the specified interface.

	this(null,mbeanInterface,true);
    
Methods Summary
private synchronized javax.management.MBeanInfobuildStandardMBeanInfo()

	return meta.buildMBeanInfo(getImplementationClass(),
				   getMBeanInterface());
    
protected synchronized voidcacheMBeanInfo(javax.management.MBeanInfo info)
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 {@link #getMBeanInfo()} is called) or sharing a unique {@link MBeanInfo} object when several StandardMBean instances have equal {@link MBeanInfo} values.

param
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.

	cachedMBeanInfo = info;
    
private static voiddebug(java.lang.String clz, java.lang.String func, java.lang.String info)

        Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_MISC, clz, func, info);
    
private static voiddebug(java.lang.String func, java.lang.String info)

        debug(dbgTag, func, info);
    
private static voiddebugX(java.lang.String func, java.lang.Throwable e)

	if (isDebugOn()) {
	    final StringWriter s = new StringWriter();
	    e.printStackTrace(new PrintWriter(s));
	    final String stack = s.toString();
	    
	    debug(dbgTag,func,"Exception caught in "+ func+"(): "+e);
	    debug(dbgTag,func,stack);
	
	    // java.lang.System.err.println("**** Exception caught in "+
	    // 			     func+"(): "+e);
	    // java.lang.System.err.println(stack);
	}
    
public java.lang.ObjectgetAttribute(java.lang.String attribute)

	return meta.getAttribute(getImplementation(),attribute);
    
public javax.management.AttributeListgetAttributes(java.lang.String[] attributes)

	try {
	    return meta.getAttributes(getImplementation(),attributes);	
	} catch (ReflectionException x) {
	    final RuntimeException r = 
		new UndeclaredThrowableException(x,x.getMessage());
	    throw new RuntimeOperationsException(r,x.getMessage());
	}
    
private javax.management.MBeanAttributeInfo[]getAttributes(javax.management.MBeanInfo info)

	final MBeanAttributeInfo[] atts = info.getAttributes();
	final MBeanAttributeInfo[] natts;
	if (atts != null) {
	    final int attlen = atts.length;
	    natts = new MBeanAttributeInfo[attlen];
	    for (int i=0; i<attlen; i++) {
		final MBeanAttributeInfo a = atts[i];
		natts[i] = new MBeanAttributeInfo(a.getName(),
						  a.getType(),
						  getDescription(a),
						  a.isReadable(),
						  a.isWritable(),
						  a.isIs());
	    }
	} else {
	    natts = null;
	}
	return natts;
    
protected synchronized javax.management.MBeanInfogetCachedMBeanInfo()
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 {@link MBeanInfo} object per instance.

return
The cached MBeanInfo, or null if no MBeanInfo is cached.
see
#cacheMBeanInfo(MBeanInfo)

	return cachedMBeanInfo;
    
protected java.lang.StringgetClassName(javax.management.MBeanInfo info)
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 {@link MBeanInfo#getClassName() info.getClassName()}.

param
info The default MBeanInfo derived by reflection.
return
the class name for the new MBeanInfo.

	if (info == null) return getImplementationClass().getName();
	return info.getClassName();
    
protected javax.management.MBeanConstructorInfo[]getConstructors(javax.management.MBeanConstructorInfo[] ctors, java.lang.Object impl)
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.

param
ctors The default MBeanConstructorInfo[] derived by reflection.
param
impl The wrapped implementation. If null is passed, the wrapped implementation is ignored and ctors is returned.
return
the MBeanConstructorInfo[] for the new MBeanInfo.

	    if (ctors == null) return null;
	    if (impl != null && impl != this) return null;
	    return ctors;
    
private javax.management.MBeanConstructorInfo[]getConstructors(javax.management.MBeanInfo info, java.lang.Object impl)

	final MBeanConstructorInfo[] ctors = 
	    getConstructors(info.getConstructors(),impl);
	final MBeanConstructorInfo[] nctors;
	if (ctors != null) {
	    final int ctorlen = ctors.length;
	    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];
			final String name = getParameterName(c,p,ii);
			final String text = getDescription(c,p,ii);
			nps[ii] = new MBeanParameterInfo(name,
							 p.getType(),
							 text);
		    }
		} else {
		    nps = null;
		}
		nctors[i] = new MBeanConstructorInfo(c.getName(),
						     getDescription(c),
						     nps);
	    }
	} else {
	    nctors = null;
	}
	return nctors;
    
protected java.lang.StringgetDescription(javax.management.MBeanInfo info)
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 {@link MBeanInfo#getDescription() info.getDescription()}.

param
info The default MBeanInfo derived by reflection.
return
the description for the new MBeanInfo.

	if (info == null) return null;
	return info.getDescription();
    
protected java.lang.StringgetDescription(javax.management.MBeanFeatureInfo info)

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 {@link MBeanFeatureInfo#getDescription() info.getDescription()}.

This method is called by {@link #getDescription(MBeanAttributeInfo)}, {@link #getDescription(MBeanOperationInfo)}, {@link #getDescription(MBeanConstructorInfo)}.

param
info The default MBeanFeatureInfo derived by reflection.
return
the description for the given MBeanFeatureInfo.

	if (info == null) return null;
	return info.getDescription();
    
protected java.lang.StringgetDescription(javax.management.MBeanAttributeInfo info)
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 {@link #getDescription(MBeanFeatureInfo) getDescription((MBeanFeatureInfo) info)}.

param
info The default MBeanAttributeInfo derived by reflection.
return
the description for the given MBeanAttributeInfo.

	return getDescription((MBeanFeatureInfo)info);
    
protected java.lang.StringgetDescription(javax.management.MBeanConstructorInfo 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 {@link #getDescription(MBeanFeatureInfo) getDescription((MBeanFeatureInfo) info)}.

param
info The default MBeanConstructorInfo derived by reflection.
return
the description for the given MBeanConstructorInfo.

	return getDescription((MBeanFeatureInfo)info);
    
protected java.lang.StringgetDescription(javax.management.MBeanConstructorInfo ctor, javax.management.MBeanParameterInfo param, int sequence)
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 {@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.

	if (param == null) return null;
	return param.getDescription();
    
protected java.lang.StringgetDescription(javax.management.MBeanOperationInfo info)
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 {@link #getDescription(MBeanFeatureInfo) getDescription((MBeanFeatureInfo) info)}.

param
info The default MBeanOperationInfo derived by reflection.
return
the description for the given MBeanOperationInfo.

	return getDescription((MBeanFeatureInfo)info);
    
protected java.lang.StringgetDescription(javax.management.MBeanOperationInfo op, javax.management.MBeanParameterInfo param, int sequence)
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 {@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.

	if (param == null) return null;
	return param.getDescription();
    
protected intgetImpact(javax.management.MBeanOperationInfo 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 {@link MBeanOperationInfo#getImpact() info.getImpact()}.

param
info The default MBeanOperationInfo derived by reflection.
return
the impact flag for the given MBeanOperationInfo.

	if (info == null) return MBeanOperationInfo.UNKNOWN;
	return info.getImpact();
    
public synchronized java.lang.ObjectgetImplementation()
Get the implementation of this MBean.

return
The implementation of this MBean.
see
#setImplementation

	return implementation;
    
public synchronized java.lang.ClassgetImplementationClass()
Get the class of the implementation of this MBean.

return
The class of the implementation of this MBean.

	if (implementation == null) return null;
	return implementation.getClass();
    
public javax.management.MBeanInfogetMBeanInfo()
Get the {@link MBeanInfo} for this MBean.

This method implements {@link javax.management.DynamicMBean#getMBeanInfo() DynamicMBean.getMBeanInfo()}.

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.
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 {@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.

	try {
	    final MBeanInfo cached = getCachedMBeanInfo();
	    if (cached != null) return (MBeanInfo)cached;
	} catch (RuntimeException x) {
	    debug("getMBeanInfo","failed to get cached MBeanInfo: "+x);
	    debugX("getMBeanInfo",x);
	}

	if (isTraceOn()) {
	    trace("getMBeanInfo", "Building MBeanInfo for "+
		  getImplementationClass().getName());
	}

	final MBeanInfo bi;
	final Object    impl;
	try {
	    synchronized (this) {
		impl = getImplementation();
		bi   = buildStandardMBeanInfo();
	    }
	} catch (NotCompliantMBeanException x) {
	    final RuntimeException r = 
		new UndeclaredThrowableException(x,x.getMessage());
	    throw new RuntimeOperationsException(r,x.getMessage());
	}

	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 MBeanInfo nmbi = 
	    new MBeanInfo(cname,text,attrs,ctors,ops,ntfs);

	try { cacheMBeanInfo(nmbi); } catch (RuntimeException x) {
	    debug("cacheMBeanInfo","failed to cache MBeanInfo: "+x);
	    debugX("cacheMBeanInfo",x);
	}

	return nmbi; 
    
public final synchronized java.lang.ClassgetMBeanInterface()
Get the Management Interface of this MBean.

return
The management interface of this MBean.

	return mbeanInterface;
    
private javax.management.MBeanNotificationInfo[]getNotifications(javax.management.MBeanInfo info)
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.

param
info The default MBeanInfo derived by reflection.
return
the MBeanNotificationInfo[] for the new MBeanInfo.

	if (info == null) return null;
        return info.getNotifications();
    
private javax.management.MBeanOperationInfo[]getOperations(javax.management.MBeanInfo info)

	final MBeanOperationInfo[] ops = info.getOperations();
	final MBeanOperationInfo[] nops;
	if (ops != null) {
	    final int oplen = ops.length;
	    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];
			final String name = getParameterName(o,p,ii);
			final String text = getDescription(o,p,ii);
			nps[ii] = new MBeanParameterInfo(name,
							 p.getType(),
							 text);
		    }
		} else {
		    nps = null;
		}
		nops[i] = new MBeanOperationInfo(o.getName(),
						 getDescription(o),
						 nps,
						 o.getReturnType(),
						 getImpact(o));
	    }
	} else {
	    nops = null;
	}
	return nops;
    
protected java.lang.StringgetParameterName(javax.management.MBeanConstructorInfo ctor, javax.management.MBeanParameterInfo param, int sequence)
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 {@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.

	if (param == null) return null;
	return param.getName();
    
protected java.lang.StringgetParameterName(javax.management.MBeanOperationInfo op, javax.management.MBeanParameterInfo param, int sequence)
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 {@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.

	if (param == null) return null;
	return param.getName();
    
public java.lang.Objectinvoke(java.lang.String actionName, java.lang.Object[] params, java.lang.String[] signature)

	return meta.invoke(getImplementation(),actionName,params,signature);
    
private static booleanisDebugOn()

        return Trace.isSelected(Trace.LEVEL_DEBUG, Trace.INFO_MISC);
    
private static booleanisTraceOn()

        return Trace.isSelected(Trace.LEVEL_TRACE, Trace.INFO_MISC);
    
public voidsetAttribute(javax.management.Attribute attribute)

	meta.setAttribute(getImplementation(),attribute);
    
public javax.management.AttributeListsetAttributes(javax.management.AttributeList attributes)

	try {
	    return meta.setAttributes(getImplementation(),attributes);	
	} catch (ReflectionException x) {
	    final RuntimeException r = 
		new UndeclaredThrowableException(x,x.getMessage());
	    throw new RuntimeOperationsException(r,x.getMessage());
	}
    
public synchronized voidsetImplementation(java.lang.Object implementation)

Replace the implementation object wrapped in this object.

param
implementation The new implementation of this MBean. The implementation object must implement the MBean interface that was supplied when this StandardMBean was constructed.
exception
IllegalArgumentException if the given implementation is null.
exception
NotCompliantMBeanException if the given implementation does not implement the MBean interface that was supplied at construction.
see
#getImplementation

	setImplementation(implementation, getMBeanInterface());
    
private synchronized voidsetImplementation(java.lang.Object implementation, java.lang.Class mbeanInterface)
Replace the implementation and management interface wrapped in this object.

param
implementation The new implementation of this MBean.
param
mbeanInterface The Management Interface exported by this MBean's implementation. If null, then this object will use standard JMX design patterns to determine the management interface associated with the given implementation.
exception
IllegalArgumentException if the given implementation is null.
exception
NotCompliantMBeanException if the mbeanInterface does not follow JMX design patterns for Management Interfaces, or if the given implementation does not implement the specified interface.

	if (implementation == null) 
	    throw new IllegalArgumentException("implementation is null");

	// test compliance
	this.meta.testCompliance(implementation.getClass(),mbeanInterface);

	// flush the cache...
	cacheMBeanInfo(null);
	this.implementation = implementation;	
	this.mbeanInterface = mbeanInterface;
	if (this.mbeanInterface == null)
	    this.mbeanInterface =
		meta.getStandardMBeanInterface(implementation.getClass());
    
private static voidtrace(java.lang.String clz, java.lang.String func, java.lang.String info)

        Trace.send(Trace.LEVEL_TRACE, Trace.INFO_MISC, clz, func, info);
    
private static voidtrace(java.lang.String func, java.lang.String info)

        trace(dbgTag, func, info);