In this chapter, we
have
seen how to create Descriptor
objects and the
necessary metadata classes for a model MBean, and we have looked at
RequiredModelMBean
and the interfaces that it must
implement. In this section, we will see how to tie all of this
information together to instrument resources as model MBeans.
The steps you must go through to instrument each of your resources as model MBeans are:
Create an instance of the resource to be managed.
Create an instance of
RequiredModelMBean
.Create the necessary metadata classes and optional descriptors for the features of the management interface.
Create the metadata for the resource (i.e., the
ModelMBeanInfo
object).Set the metadata of
RequiredModelMBean
to the metadata for the resource (from Step 3) and the resource to be managed through theModelMBean
interface.
As in the previous chapters, we will use the sample application for all of our examples. This will allow you to compare and contrast the other MBean types with model MBeans.
In the examples presented here we will look at the application class
Controller
, which
acts as the JMX agent. For the example code in this chapter, the
Controller
class is responsible for creating the
resources to be managed, instrumenting them as model MBeans, and
registering them with the MBean server.
The first two steps are to create an instance of the managed resource
(in this example, the Queue
) and to create the
RequiredModelMBean
instance:
// . . . Queue queue = new Queue( ); RequiredModelMBean queueModelMBean = new RequiredModelMBean( ); // . . .
Next, we must create the necessary model MBean metadata classes (only some of the attributes and operations are shown, as the examples can be quite lengthy). First we’ll create the attributes:
// There are 10 attributes . . . ModelMBeanAttributeInfo[] attributeInfo = new ModelMBeanAttributeInfo[10]; attributeInfo[0] = new ModelMBeanAttributeInfo( "QueueSize", "java.lang.Integer", "The maximum size of the queue.", true, true, false, ); DescriptorSupport desc = attributeInfo[0].getDescriptor( ); desc.setField("getMethod", "getQueueSize"); desc.setField("setMethod", "setQueueSize"); desc = new DescriptorSupport( new String[] { "name=NumberOfItemsProcessed", "descriptorType=attribute", "getMethod=getNumberOfItemsProcessed", } ); attributeInfo[1] = new ModelMBeanAttributeInfo( "NumberOfItemsProcessed", "java.lang.Long", "The number of work units processed.", true, false, false, ); // . . . other attributes . . . desc = new DescriptorSupport( new String[] { "name=NumberOfConsumers", "descriptorType=attribute", "getMethod=getNumberOfConsumers", } ); attributeInfo[9] = new ModelMBeanAttributeInfo( "NumberOfConsumers", "java.lang.Integer", "No. of consumer threads currently feeding the queue.", true, false, false, );
Then we’ll create the metadata for the operations:
// . . . ModelMBeanOperationInfo[] operationInfo = new ModelMBeanOperationInfo[13]; desc = new DescriptorSupport( new String[] { "name=suspend", "descriptorType=operation", "role=operation", } ); operationInfo[0] = new ModelMBeanOperationInfo( "suspend", "Suspends activity in the queue.", new MBeanParameterInfo[0], Void.TYPE.getName( ), MBeanOperationInfo.ACTION, ); desc = new DescriptorSupport( new String[] { "name=resume", "descriptorType=operation", } ); operationInfo[1] = new ModelMBeanOperationInfo( "resume", "Resumes activity in the queue.", new MBeanParameterInfo[0], Void.TYPE.getName( ), MBeanOperationInfo.ACTION, desc ); // . . .
One difference between
model MBeans and other MBean types is
that operation metadata must be created for attribute getters and
setters. This is probably an oversight of the JMX RI, but one that
you must deal with if you wish to use it. For each getter and setter,
you must create a ModelMBeanOperationInfo
instance, such that a writable attribute has two
ModelMBeanOperationInfo
instances (one for the
getter and one for the setter). A read-only attribute will have only
one (for the getter). The following example shows how to create the
ModelMBeanOperationInfo
objects for the getters
and setters for the attributes for Queue
.
Note
that only QueueSize
has a setter.
// . . .
desc = new DescriptorSupport(
new String[] {
"name=getQueueSize",
"descriptorType=operation",
"role=getter"
}
);
operationInfo[2] = new ModelMBeanOperationInfo(
"getQueueSize",
"Getter for QueueSize",
new MBeanParameterInfo[0],
Integer.TYPE.getName( ),
MBeanOperationInfo.INFO,
desc
);
desc = new DescriptorSupport(
new String[] {
"name=setQueueSize",
"descriptorType=operation",
"role=setter"
}
);
MBeanParameterInfo[] parms = new MBeanParameterInfo[1];
parms[0] = new MBeanParameterInfo(
"value",
"java.lang.Integer",
"value"
);
operationInfo[3] = new ModelMBeanOperationInfo(
"setQueueSize",
"Setter for QueueSize",
parms,
Void.TYPE.getName( ),
MBeanOperationInfo.ACTION,
desc
);
// . . . other getters. ..
desc = new DescriptorSupport(
new String[] {
"name=getNumberOfSuppliers",
"descriptorType=operation",
"role=getter"
}
);
// . . .other getters/setters. . .
operationInfo[12] = new ModelMBeanOperationInfo(
"getNumberOfSuppliers",
"Getter for NumberOfSuppliers",
new MBeanParameterInfo[0],
Integer.TYPE.getName( ),
MBeanOperationInfo.INFO,
desc
);
Because no explicit constructors are required and there are no
notifications, the ModelMBeanInfo
object can be
created:
// . . .
ModelMBeanInfo mbeanInfo = new ModelMBeanInfoSupport(
queue.getClass().getName( ),
"Queue Model MBean",
attributeInfo,
null,
operationInfo,
null
);
queueModelMBean.setModelMBeanInfo(mbeanInfo);
queueModelMBean.setManagedResource(queue, "ObjectReference");
MBeanServer mbeanServer = MBeanServerFactory.createMBeanServer( );
mbeanServer.registerMBean(queueModelMBean, objName);
// . . .
Notice the emphasized line in this example. The managed resource
isn’t the instance of
RequiredModelMBean
(whose instance variable is
queueModelMBean
), but the instance of the
Queue
(whose instance variable is
queue
). When we were creating standard and dynamic
MBeans, the managed resource and the MBean were physically the same
object. Although they are logically still one
entity, with model MBeans the managed resource and the MBean (i.e.,
the instance of RequiredModelMBean
) are not
physically the same object.
In creating the metadata for the model MBean itself, we have allowed
the ModelMBeanInfoSupport
constructor to create a
default descriptor. If you would like to create a descriptor for the
ModelMBeanInfo
object that represents your MBean,
there should be sufficient information in this chapter to help you do
that.
Notice that we can pass null
as parameter values
for the constructors and notification metadata (we can also pass
null
for attribute or operation metadata if there
are no attributes or operations, respectively). In previous sections
(and the previous chapter), we covered at length how to create
constructor and notification metadata. If you need to create these
metadata classes, simply pass them as the appropriate parameters to
the ModelMBeanInfoSupport
constructor.
Get Java Management Extensions now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.