JMX - atomic access to multiple attributes on the same MBean

I was recently reading an excellent article by JMX Spec Lead Éamonn McManus called MXBeans in Java SE 6: Bundling Values Without Special JMX Client Configurations, which describes a great Java 6 platform feature related to management - that of supporting MXBeans - gone are your classpath issues with proprietory serialized Objects being sent over a JMX connection.

Although MXBeans are a very suitable general-purpose approach to this question, and MXBeans are what I'd recommend if you're able to use Java 6 and are able to choose your own data model, they're not the only way of getting access to MBean attributes in an atomic manner. This entry explains another approach to a slightly different problem-space - that of accessing different attributes in an atomic manner, rather than grouping the attributes together into a single, composite attribute.

This can be done by providing a couple of helper classes that work hand-in-hand together to provide the atomicity, hiding all the complexity from the user. The client uses a SnapshotProxy MBean instead of a traditional proxy, and the MBean on the server is registered as a SynchronizedStandardMBean instead of as a plain StandardMBean.

SynchronizedStandardMBean

As described in Éamonn's article, the only way of an MBean getting a single, atomic request to read more than one attribute at the same time is by implementing the DynamicMBean.getAttributes method. Implementing this from scratch in your own Dynamic MBean is indeed a painful task. But this actually can be done really simply, given the help that we can get from the StandardMBean class. It simply involves subclassing and overriding the one method.

So how do we implement getAttributes to make the access to more than one attribute synchronized? Simple! We can execute the setAttributes and getAttributes methods in a block that synchronizes on the underlying MBean implementation object:

public class SynchronizedStandardMBean extends StandardMBean {

    public AttributeList setAttributes(AttributeList attributes) {
        synchronized (getImplementation()) {
            return super.setAttributes(attributes);
        }
    }

    public AttributeList getAttributes(String[] attributes) {
        synchronized (getImplementation()) {
            return super.getAttributes(attributes);
        }
    }
}

 

By implementing this generic helper class, all calls to simultaneously access multiple attributes are synchronized on the underlying object instance. This means that we can write our MBean implementation taking into account that certain attributes are coherent, and only update those attributes in a synchronized block.

So there we have the first part - a SynchronizedStandardMBean implementation in a few lines of code that permits the atomic access to more than one MBean attribute at a time. But this doesn't really help the client-side developer, since calling MBeanServerConnection.getAttributes() isn't type-safe and it is much less friendly than just using an MBean proxy

SnapshotProxies

JMX's use of proxies via the MBeanServerInvocationHandler APIs is extremely powerful, permitting type-safe programming for client applications. Out of the box, JMX provides a simple proxy implementation that forward the typed requests to an MBeanServer using the MBeanServerConnection API.

One can also enrich the code in the proxy logic. In our case, we're interested in atomic access to multiple attributes, so our SnapshotProxy will use a single call to MBeanServerConnection.getAttributes() to read the value of all the attributes of a given MBean in a single shot, and then respond to 'getter' requests on individual attributes from the data returned by the single snapshot.

The code for such a SnapshotProxy is pretty straight-forward once you've got your mind around the java.lang.reflection APIs, but is a little longer than the above. It needs to do some work to introspect the MBean interface, convert method names to attribute names, read all the attributes at once using a call to MBeanServerConnection.getAttributes() and then respond to individual proxy requests from the results.

... and that is the subject of my next blog article.

Comments:

Post a Comment:
Comments are closed for this entry.
About

nickstephen

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today