ModelMBean attributes problem

Hi all,

I have a simple model mbean to expose, however from the jconsole I can see only the attribute names, not their values (everything works fine from the agent):

/**

* This is the class to expose

*/

publicclass ModelSample{

privateboolean started;

privateint changes;

public ModelSample(){

this.started =false;

this.changes = 0;

}

publicboolean isStarted(){

return started;

}

publicint getChanges(){

return changes;

}

publicvoid start(){

started =true;

changes++;

}

publicvoid stop(){

started =false;

changes++;

}

}

/**

* This is the agent

*/

publicclass ModelAgent{

privatestatic MBeanServer server = ManagementFactory

.getPlatformMBeanServer();

private ObjectName oname;

private ModelMBeanAttributeInfo[] attributes;

private ModelMBeanOperationInfo[] operations;

private ModelMBeanConstructorInfo[] constructors;

private ModelMBeanNotificationInfo[] notifications;

private ModelMBeanInfo info;

/**

* Creates a new <tt>ModelAnget</tt> object.

*/

public ModelAgent()throws Exception{

oname = ObjectName.getInstance("model","bean","sample");

buildMBeanInfo();

RequiredModelMBean mbean =new RequiredModelMBean(this.info);

mbean.setManagedResource(new ModelSample(),"ObjectReference");

server.registerMBean(mbean, oname);

waitForEnterPressed();

printMBeanInfo(oname,"sample");

waitForEnterPressed();

server.unregisterMBean(oname);

}

privatestaticvoid sleep(int millis){

try{

Thread.sleep(millis);

}catch (InterruptedException e){

return;

}

}

privatevoid printMBeanInfo(ObjectName mbeanObjectName, String mbeanName){

echo("\n>>> Getting the management information for the " + mbeanName

+":" + mbeanObjectName +" MBean");

echo("using the getMBeanInfo method of the MBeanServer");

sleep(1000);

ModelMBeanInfo info =null;

try{

info = (ModelMBeanInfo) (server.getMBeanInfo(mbeanObjectName));

if (info ==null){

echo("\nModelMBeanInfo from JMX Agent is null!");

return;

}

}catch (Exception e){

echo("\t!!! ModelAgent:printMBeanInfo: Could not get MBeanInfo object for "

+ mbeanName

+" exception type "

+ e.getClass().toString()

+":" + e.getMessage() +"!!!");

e.printStackTrace();

return;

}

echo("\nCLASSNAME: \t" + info.getClassName());

echo("\nDESCRIPTION: \t" + info.getDescription());

try{

echo("\nMBEANDESCRIPTOR: \t"

+ (info.getMBeanDescriptor()).toString());

}catch (Exception e){

echo("\nMBEANDESCRIPTOR: \tNone");

}

echo("\nATTRIBUTES");

MBeanAttributeInfo[] attrInfo = (info.getAttributes());

if (attrInfo.length > 0){

for (int i = 0; i < attrInfo.length; i++){

echo("\n ** NAME: \t" + attrInfo[i].getName());

echo("DESCR: \t" + attrInfo[i].getDescription());

echo("TYPE: \t" + attrInfo[i].getType() +"\tREAD: "

+ attrInfo[i].isReadable() +"\tWRITE: "

+ attrInfo[i].isWritable());

echo("DESCRIPTOR: \t"

+ (((ModelMBeanAttributeInfo) attrInfo[i])

.getDescriptor()).toString());

}

}else

echo(" ** No attributes **");

MBeanConstructorInfo[] constrInfo = info.getConstructors();

echo("\nCONSTRUCTORS");

if (constrInfo.length > 0){

for (int i = 0; i < constrInfo.length; i++){

echo("\n ** NAME: \t" + constrInfo[i].getName());

echo("DESCR: \t" + constrInfo[i].getDescription());

echo("PARAM: \t" + constrInfo[i].getSignature().length

+" parameter(s)");

echo("DESCRIPTOR: \t"

+ (((ModelMBeanConstructorInfo) constrInfo[i])

.getDescriptor()).toString());

}

}else

echo(" ** No Constructors **");

echo("\nOPERATIONS");

MBeanOperationInfo[] opInfo = info.getOperations();

if (opInfo.length > 0){

for (int i = 0; i < opInfo.length; i++){

echo("\n ** NAME: \t" + opInfo[i].getName());

echo("DESCR: \t" + opInfo[i].getDescription());

echo("PARAM: \t" + opInfo[i].getSignature().length

+" parameter(s)");

echo("DESCRIPTOR: \t"

+ (((ModelMBeanOperationInfo) opInfo[i])

.getDescriptor()).toString());

}

}else

echo(" ** No operations ** ");

echo("\nNOTIFICATIONS");

MBeanNotificationInfo[] notifInfo = info.getNotifications();

if (notifInfo.length > 0){

for (int i = 0; i < notifInfo.length; i++){

echo("\n ** NAME: \t" + notifInfo[i].getName());

echo("DESCR: \t" + notifInfo[i].getDescription());

echo("DESCRIPTOR: \t"

+ (((ModelMBeanNotificationInfo) notifInfo[i])

.getDescriptor()).toString());

}

}else

echo(" ** No notifications **");

echo("\nEnd of MBeanInfo print");

}

privatefinalvoid buildMBeanInfo()throws Exception{

Class<ModelSample> bean = ModelSample.class;

// this.descriptor = new DescriptorSupport()

attributes =new ModelMBeanAttributeInfo[2];

operations =new ModelMBeanOperationInfo[3];

constructors =new ModelMBeanConstructorInfo[0];

notifications =new ModelMBeanNotificationInfo[1];

// Descriptor stateD = new DescriptorSupport();

// stateD.setField("name", "started");

attributes[0] =new ModelMBeanAttributeInfo("started", boolean.class

.getName(),"status", true, false,true);

attributes[1] =new ModelMBeanAttributeInfo("Changes", int.class

.getName(),"number of changes", true, false,false);

operations[0] =new ModelMBeanOperationInfo("start",

"Start this mbean", null,"void", MBeanOperationInfo.ACTION);

operations[1] =new ModelMBeanOperationInfo("stop","Stop this mbean",

null,"void", MBeanOperationInfo.ACTION);

operations[2] =new ModelMBeanOperationInfo("isStarted",

"Gets the started status", null, boolean.class.getName(),

MBeanOperationInfo.INFO);

String[] notifTypes ={ AttributeChangeNotification.ATTRIBUTE_CHANGE};

notifications[0] =new ModelMBeanNotificationInfo(notifTypes,

AttributeChangeNotification.class.getName(),

"MBean state changed");

this.info =new ModelMBeanInfoSupport(ModelSample.class.getName(),

"Sample model mbean", attributes, constructors, operations,

notifications);

String[] s ={"name=" + this.oname,"log=f","descriptorType=mbean",

"displayName=SampleModel","currencyTimeLimit=5",

"persistPolicy=Never"};

Descriptor inDescriptor =new DescriptorSupport(s);

this.info.setMBeanDescriptor(inDescriptor);

}

privatestaticvoid echo(String msg){

System.out.println(msg);

}

privatestaticvoid waitForEnterPressed(){

try{

echo("\nPress Enter to continue...");

boolean done =false;

while (!done){

char ch = (char) System.in.read();

if (ch < 0 || ch =='\n'){

done =true;

}

}

echo("");

}catch (IOException e){

e.printStackTrace();

}

}

/**

* @param args

*/

publicstaticvoid main(String[] args)throws Exception{

new ModelAgent();

}

}

Finally, what shall I do to allow a model mbean to send notifications?

Thanks in advance,

Michele

[14995 byte] By [michele81a] at [2007-10-3 11:31:56]
# 1

In order to get the Model MBean to call your methods when your attributes are accessed, you need to include a getMethod field in each attribute's Descriptor. The value of this field is a string that is the method name, so "isStarted" and "getChanges" in your example. There must also be an operation of the same name in the ModelMBeanOperationInfo[].

emcmanusa at 2007-7-15 13:58:40 > top of Java-index,Core,Monitoring & Management...
# 2
Thanks. And what about notifications?, If I'm right is the RequiredModelMBean object which has to be "instructed" about notifications, but how to do that?Thanks,Michele
michele81a at 2007-7-15 13:58:40 > top of Java-index,Core,Monitoring & Management...
# 3

Hi Michele,

You will find some sample code that builds a ModelMBeanInfo in my blog here:

<a href="http://blogs.sun.com/jmxetc/entry/dynamicmbeans%2C_modelmbeans%2C_and_pojos...">Dynamic MBeans, Model MBeans, and POJOs</a>.

I have highlighted two non trivial steps that you need to perform when creating your ModelMBeanInfo.

hope this helps,

PS: I haven't said anything about notifications though...

-- daniel

http://blogs.sun.com/jmxetc

Message was edited by:

dfuchs

dfuchsa at 2007-7-15 13:58:40 > top of Java-index,Core,Monitoring & Management...
# 4
Thanks Daniel. It would be really nice to have an example of ModelMBean + notificationsMichele
michele81a at 2007-7-15 13:58:40 > top of Java-index,Core,Monitoring & Management...
# 5

Wel i got it working by making just a few changes to the code given above.

First : Add the following code snippet to ModelSample.java

public int getChanges() {

return changes;

}

Secondly : Add the following code snippet to ModelAgent.java

// Add descriptor for the attribute

Descriptor changeDesc = new DescriptorSupport();

changeDesc .setField("name", "changes");

changeDesc .setField("descriptorType", "attribute");

changeDesc .setField("displayName", "changes");

changeDesc .setField("getMethod", "getChanges");

changeDesc .setField("currencyTimeLimit", "20");

attributes[1] = new ModelMBeanAttributeInfo("changes", int.class

.getName(), "number of changes", true, false, false, changeDesc );

// Add operation targetting getChanges()

operations = new ModelMBeanOperationInfo[3];

operations[3] = new ModelMBeanOperationInfo("getChanges",

"Gets the changes value", null, "java.lang.Integer",

MBeanOperationInfo.INFO);

Testing it via Jconsole

1) Click Start button in operations tab.

2) Click GetChanges in operations tab.

3) View the changes value in attributes tab against 'changes'

Hope this helped !!!

- Deepthi

dips80a at 2007-7-15 13:58:40 > top of Java-index,Core,Monitoring & Management...
# 6
attributes[1] = new ModelMBeanAttributeInfo("Changes", int.class.getName(), "number of changes", true, false, false);The 'Changes' variable name has to be given as 'changes'. You will be able to retrieve the attribute value.- Deepthi
dips80a at 2007-7-15 13:58:40 > top of Java-index,Core,Monitoring & Management...