Remoting for JMX MBeans
allesmallachen Mar 7, 2006 5:24 AMHi,
I have a question regarding JMX MBean communication.
In my project I need asynchronous calls and dynamic lookup among other things.
This is so easy with JBoss Remoting (thumbs up for the developers!:-))
Now I need some of my object to be manageable via JMX. Accessing
remote objects is easy with JMX, but the problem I have is that I have to be able to switch between RMI, HTTP and HTTPS
for transport. JMX comes only with a RMI connector out of the box. I have found a free HTTP Adaptor
in the MX4J project, but I think that's not the same as a HTTP Connector (I'm new to JMX, so I might be wrong)
Therefore I used the following code to make my MBeans talk over JBoss Remoting.
It uses some classes from the Spring framework to construct a RequiredModelMBean that wraps a TransporterClient:
This example is based on the basic transporter example included in the JBoss Remoting 1.4.0 release:
The client:
public void makeClientCall() throws Exception { //added setName/getName methods to the CustomerProcessor // interface to edit the name via jconsole CustomerProcessor processor = (CustomerProcessor) TransporterClient.createTransporterClient(locatorURI, CustomerProcessor.class); //create a RequiredModelMBean using Spring's handy InterfaceBasedMBeanInfoAssembler Class[] managedInterfaces = new Class[] { CustomerProcessor.class }; InterfaceBasedMBeanInfoAssembler assembler = new InterfaceBasedMBeanInfoAssembler(); assembler.setManagedInterfaces(managedInterfaces); RequiredModelMBean mBean = new RequiredModelMBean(); mBean.setModelMBeanInfo(assembler.getMBeanInfo(processor, "processor:name=clientProcessor")); mBean.setManagedResource(processor, "ObjectReference"); //register the MBean to the local MBean server MBeanServer server= ManagementFactory.getPlatformMBeanServer(); server.registerMBean(mBean,new ObjectName("processor:name=clientProcessor")); processor.setName("newName");//this can be done via jconsole now TransporterClient.destroyTransporterClient(processor); }
The server:
public void start() throws Exception { CustomerProcessor processor = new CustomerProcessorImpl(); Class[] managedInterfaces = new Class[] { CustomerProcessor.class }; InterfaceBasedMBeanInfoAssembler assembler = new InterfaceBasedMBeanInfoAssembler(); assembler.setManagedInterfaces(managedInterfaces); RequiredModelMBean mBean = new RequiredModelMBean(); mBean.setModelMBeanInfo(assembler.getMBeanInfo(processor, "processor:name=serverProcessor")); mBean.setManagedResource(processor, "ObjectReference"); MBeanServer mb = ManagementFactory.getPlatformMBeanServer(); mb.registerMBean(mBean, new ObjectName("processor:name=serverProcessor")); server = TransporterServer.createTransporterServer(locatorURI, processor); }
You need to add -Dcom.sun.management.jmxremote when starting the client and server to make
the MBeanServer available for remote calls. You should also add a System.in.read() somewhere
to keep the server and client alive until you press enter.
With this setup I'm able to change the name property of the CustomerProcessor on the client and
on the server side and changes are reflected on both sides. This can be done programmatically and via
the jconsole. And the communication is done using the transporter mechanism of JBoss Remoting.
My question now is (sorry for the long introduction):
Is this a good approach to let JMX MBeans talk to each other. Are there any drawbacks that I might have missed?
I have the JBoss Remoting stuff already in place in my application, so I thought I just use it also for
my MBeans. You can argue that MBean communication is build into JMX already, but how can I switch between
transport protocols and maybe make asynchronous calls between MBeans?
I'm interested in your thoughts, so if you can spare some time, please leave a short comment:-)
Chris