participate


JMX - How to expose methods of a class dynamically.. using Model Mbean???
<<   Back to Forum  |   Give us Feedback
This topic has 4 replies on 1 page.
CoolestAth
Posts:5
Registered: 1/12/06
How to expose methods of a class dynamically.. using Model Mbean???   
Nov 14, 2006 2:31 PM

 
Hi,
Would like to expose methods of my POJO's dynamically.
for ex : my POJO wil have few getter and setter methods like getName(), setName()
Another POJO wil have methods like getAccntDetails(), setAccntDetails().
so how do i write a common Mbean implementation to expose both of these by JMX..using Model Mbean.
i saw a few examples, but at everyplace we need to mention those methods.
what if i have to adda a new POJO later.

Is this possible?

Thanks
Athahar
 
emcmanus
Posts:206
Registered: 1/27/98
Re: How to expose methods of a class dynamically.. using Model Mbean???   
Nov 15, 2006 8:42 AM (reply 1 of 4)  (In reply to original post )

 
Athahar,

As an alternative to Model MBeans, you could consider the approach described in <http://weblogs.java.net/blog/emcmanus/archive/2006/10/build_your_own.html>.

If you do want to use Model MBeans, the example code in the documentation of the package javax.management.modelmbean would be a good starting point <http://download.java.net/jdk6/docs/api/javax/management/modelmbean/package-summary.html>. But as you've probably noticed it's quite a lot of work to build a Model MBean.

Here's a class that makes a Model MBean based on the public getters in an object. It should be straightforward to generalize it to include setters too.

public class POJOMBeanFactory {
    public static ModelMBean makeMBean(Object resource) {
	try {
	    return makeMBean2(resource);
	} catch (RuntimeException e) {
	    throw e;
	} catch (Exception e) {
	    throw new RuntimeException(e);
	}
    }
 
    private static ModelMBean makeMBean2(Object resource)
	    throws JMException, InvalidTargetObjectTypeException {
	Method[] methods = resource.getClass().getMethods();
	List<Method> getters = new ArrayList<Method>();
	for (Method method : methods) {
	    if (method.getName().startsWith("get") &&
		    !method.getName().equals("get") &&
		    !method.getName().equals("getClass") &&
		    method.getParameterTypes().length == 0 &&
		    method.getReturnType() != void.class)
		getters.add(method);
	}
	int ngetters = getters.size();
	ModelMBeanAttributeInfo[] attrs = new ModelMBeanAttributeInfo[ngetters];
	ModelMBeanOperationInfo[] ops = new ModelMBeanOperationInfo[ngetters];
	for (int i = 0; i < ngetters; i++) {
	    Method getter = getters.get(i);
	    String attrName = getter.getName().substring(3);
	    Descriptor attrD =
		new DescriptorSupport(new String[] {
					  "name=" + attrName,
					  "descriptorType=attribute",
					  "getMethod=" + getter.getName()
				      });
	    attrs[i] = new ModelMBeanAttributeInfo(attrName,
						   attrName,
						   getter,
						   null,
						   attrD);
	    ops[i] = new ModelMBeanOperationInfo(getter.getName(),
						 getter);
	}
	ModelMBeanInfo mmbi =
	    new ModelMBeanInfoSupport(resource.getClass().getName(),
				      resource.getClass().getName(),
				      attrs,
				      null,  // constructors
				      ops,
				      null); // notifications
	ModelMBean mmb = new RequiredModelMBean(mmbi);
	mmb.setManagedResource(resource, "ObjectReference");
	return mmb;
    }
}
 
CoolestAth
Posts:5
Registered: 1/12/06
Re: How to expose methods of a class dynamically.. using Model Mbean???   
Nov 15, 2006 8:59 PM (reply 2 of 4)  (In reply to #1 )

 
Hi Eamonn,
Thanks .. I could work on that, and i could get the getter working for the POJO's.. but i tried a lot on trying to expose the setter methods..

 private static ModelMBean makeMBean2(Object resource)
	    throws JMException, InvalidTargetObjectTypeException {
    	
	Method[] methods = resource.getClass().getMethods();
	
	List<Method> operations = new ArrayList<Method>();
	List<Method> getters = new ArrayList<Method>();
	List<Method> setters = new ArrayList<Method>();
	
	for (Method method : methods) {
	    
		if (method.getName().startsWith("get") &&
		    !method.getName().equals("get") &&
		    !method.getName().equals("getClass") &&
		    method.getParameterTypes().length == 0 &&
		    method.getReturnType() != void.class)
		{
			operations.add(method);
			getters.add(method);
	    
		}
	    	
	    
	    if (method.getName().startsWith("set") &&
			    !method.getName().equals("set"))
	    {
	    	operations.add(method);
	    	setters.add(method);
	    }
		    
	}
	
	
	int opsSize = operations.size();
	int ngetters = getters.size();
	
	ModelMBeanAttributeInfo[] attrs = new ModelMBeanAttributeInfo[opsSize];
	
	ModelMBeanOperationInfo[] ops = new ModelMBeanOperationInfo[opsSize];
	
	
	for (int i = 0; i < ngetters; i++) {
	    Method getter = getters.get(i);
	    Method setter = setters.get(i);
	    
	    String attrName = getter.getName().substring(3);
	    
	    Descriptor attrD =
		new DescriptorSupport(new String[] {
					  "name=" + attrName,
					  "descriptorType=attribute",
					  "getMethod=" + getter.getName()
				      });
	    attrs[i] = new ModelMBeanAttributeInfo(attrName,
						   attrName,
						   getter,
						   setter,
						   attrD);
	    
	    ops[i] 			= new ModelMBeanOperationInfo(getter.getName(),
						 		getter);
	    ops[ngetters+i] = new ModelMBeanOperationInfo(setter.getName(),
	    						setter);
	}
	
	
	
	
	ModelMBeanInfo mmbi =
	    new ModelMBeanInfoSupport(resource.getClass().getName(),
				      resource.getClass().getName(),
				      attrs,
				      null,  // constructors
				      ops,
				      null); // notifications
	ModelMBean mmb = new RequiredModelMBean(mmbi);
	mmb.setManagedResource(resource, "ObjectReference");
	return mmb;
    }



Can u please tell me where i'm going wrong?

Exception in thread "main" java.lang.RuntimeException: javax.management.IntrospectionException: bad getter arg count
at POJOMBeanFactory.makeMBean(POJOMBeanFactory.java:27)
at POJOMbeanAgent.<init>(POJOMbeanAgent.java:34)
at POJOMbeanAgent.main(POJOMbeanAgent.java:69)
Caused by: javax.management.IntrospectionException: bad getter arg count
at javax.management.MBeanAttributeInfo.attributeType(MBeanAttributeInfo.java:236)
at javax.management.MBeanAttributeInfo.<init>(MBeanAttributeInfo.java:122)
at javax.management.modelmbean.ModelMBeanAttributeInfo.<init>(ModelMBeanAttributeInfo.java:200)
at POJOMBeanFactory.makeMBean2(POJOMBeanFactory.java:68)
at POJOMBeanFactory.makeMBean(POJOMBeanFactory.java:23)



Thanks
Athahar
 
michele81
Posts:96
Registered: 7/14/05
Re: How to expose methods of a class dynamically.. using Model Mbean???   
Nov 16, 2006 1:33 AM (reply 3 of 4)  (In reply to #2 )

 
Hi Athahar,

I guess your setter methods want an argument and have a void return type. I think line 27 is

operations.add(method);


for setter methods



Hope this helps,
Michele
 
dfuchs
Posts:416
Registered: 1/5/06
Re: How to expose methods of a class dynamically.. using Model Mbean???   
Nov 16, 2006 2:33 AM (reply 4 of 4)  (In reply to #3 )

 
Hi Athahar,

The logic that builds up the ModelMBeanAttributeInfo[] is wrong.

1) There's no guarantee that there will be as many getters as setters - in other
words, in the general case, getters.size() != setters.size()

2) There's no guarantee that getters.get(i) and setters.set(i) relates to the same
attribute: getters.get(i) could be the method <i>getFoo()</i> and setters.get(i)
could be the method <i>setBar()</i>

You can't do everything in a single loop, you need 3 loops:

What you would need to do is:
0) Allocate an array list to contain a yet unknown number of ModelMBeanAttributeInfo
1) loop over getters:
1.1) for each getter extract the attribute name
1.2) from the attribute name, construct the name of the corresponding setter method.
1.3) see whether you find a setter method by that name in setters
1.4) remove the setter method from the setters list.
1.5) construct the ModelMBeanAttributeInfo for that attribute, add it to the list
2) At this point, the setters list should only contain setters for which there was no
getter (will be empty unless there was a setFoo() without a getFoo() - which
usually won't happen). But just in case you will need to loop over the remaining
setters:
2.1) for each getter extract the attribute name
2.2) from the attribute name, construct the name of the corresponding setter method.
2.3) construct the ModelMBeanAttributeInfo for that attribute, add it to the list
3) Convert the ArrayList<ModelMBeanAttributeInfo> into an array (use
toArray())
4) Now loop over operations
4.1) for each operations construct a ModelMBeanOperationInfo object.


Hope this helps,

-- daniel
http://blogs.sun.com/jmxetc
 
This topic has 4 replies on 1 page.
Back to Forum
 
Read the Developer Forums Code of Conduct

Click to email this message Email this Topic

Edit this Topic
  
 
 
Forums Statistics
    Users Online : 25
  • Guests : 129

About Sun forums
  • Sun Forums is a large collection of user generated discussions. It is here to help you ask questions, find answers, and participate in discussions.

    Check out our guide on Getting started with Sun Forums for a full walkthrough of how to best leverage the benefits of this community.

Powered by Jive Forums