Java: July 2009 Archives

Somehow I had survived in the Java wold until now without ever having the pleasure of writing an MBean. MBeans and JMX in general are really cool, but like those full coverage integration tests, they’re one of those things that often slips through the cracks until you have your first major production incident.

This time I’m trying to be good. I’m actually implementing the configuration harness that I’m using for all of my applications with a built in Standard MBean. This MBean provides easy JMX access to inspect and update configuration during runtime.

I followed this tutorial to get going. Note that it has no date (always date your technical blog entries!) It’s pretty good but I had to jump through a couple of hoops to get it working. Here is the story of those jumps.

A Singleton Can Not Be a Standard MBean

I didn’t see this mentioned anywhere, but it turns out to be true. Standard MBeans must have a public default constructor. If they do not, you’ll see this friendly stack trace:

java.lang.NullPointerException
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerMBean(DefaultMBeanServerInterceptor.java:303)
    at com.sun.jmx.mbeanserver.JmxMBeanServer.registerMBean(JmxMBeanServer.java:482)
    at foo.bar.Configamajig.bootstrap(Configamajig.java:74)

Yeah, it took me awhile to figure that out.

Anyway, I solved the problem by creating a static class adapter for my singleton. The static adapter just proxied the methods of the singleton with a provided public default constructor. For this to be reliable I make sure that I bootstrap my singleton before I create the MBean (just in case it calls some of those methods).

MBean Concrete Class Naming Is Not Flexible

The example had an MBean interface HelloMBean with a concrete implementing class by the name Hello. As it turns out this was not just to make the tutorial easy to follow. It’s required for the MBean to work! This turned out really nice since my concrete class was an adapter (per the above step). As a result my MBean interface must contain the work ‘adapter’ to comply with this convention.

The guys who came up with this must have forgotten that convention over configuration implies that you can override the convention with configuration if you so desire.

Anyway, to help you Google searcher’s find this solution, here’s the stack trace:

javax.management.NotCompliantMBeanException: MBean class foo.bar.ConfigamajigMBeanImpl does not implement DynamicMBean, neither follows the Standard MBean conventions (javax.management.NotCompliantMBeanException: Class foo.bar.ConfigamajigMBeanImpl is not a JMX compliant Standard MBean) nor the MXBean conventions (javax.management.NotCompliantMBeanException: foo.bar.ConfigamajigMBeanImpl: Class foo.bar.ConfigamajigMBeanImpl is not a JMX compliant MXBean)
    at com.sun.jmx.mbeanserver.Introspector.checkCompliance(Introspector.java:160)
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerMBean(DefaultMBeanServerInterceptor.java:305)
    at com.sun.jmx.mbeanserver.JmxMBeanServer.registerMBean(JmxMBeanServer.java:482)
    at foo.bar.Configamajig.bootstrap(Configer.java:75)
0 Votes

About this Archive

This page is an archive of entries in the Java category from July 2009.

Java: June 2009 is the previous archive.

Java: November 2009 is the next archive.

Find recent content on the main index or look in the archives to find all content.