Skip to main content

Mustang Beta and the JMX API

Posted by emcmanus on February 15, 2006 at 8:52 AM PST

As you'll no doubt have read href="">elsewhere,
the Mustang Beta Release is href="">now available. There are
plenty of improvements in plenty of areas, including the JMX

The improvements to the JMX API are incremental changes to
existing functionality, rather than entirely new features. The
new features will arrive in Dolphin (Java SE 7), as defined by
JSR 255. (The
members of the JSR 255 Expert Group were also closely involved
in the JMX API changes made in Mustang.)

We don't expect there to be any significant changes to the JMX
API beyond the Beta. If you felt that the weekly
Mustang snapshots from
might be too risky or
too volatile, but you're tempted by the new features, now you
can download the Beta and play with them. We think the Beta is
pretty solid, but let us know through
if you find a problem. In
particular, if you find a regression (code that used
to work on Tiger but doesn't work on Mustang), then you might
be eligible for the href="">Mustang
regression challenge.

What's changed?

The two biggest changes to the JMX API in Mustang concern
MXBeans and Descriptors.

I wrote about
MXBeans href="">
recently. MXBeans provide a way to package related
information together in an MBean without requiring any special
configuration for clients that interact with that MBean. This
is an incremental change, because MXBeans already existed in
J2SE 5.0, in the package href=""> What's new is that
users can now define their own MXBeans, in addition to the
standard set defined in

I also wrote about Descriptors href="">
a while back. Descriptors give you a convenient way to
attach arbitrary extra metadata to your MBeans. This is an
incremental change because Descriptors have always existed in
the JMX API, but only in conjunction with href="">
Model MBeans. In Mustang, Descriptors are available with
all types of MBeans. This helps to erase the somewhat
arbitrary distinctions between different sorts of MBeans,
notably Open MBeans and Model MBeans.

Here are a few of the other improvements that Mustang brings to
the JMX API.


For obscure compatibility reasons, we weren't able to generify
the JMX API in Tiger. This has been fixed in Mustang. So
now returns a
Set<ObjectName> rather than a plain

ObjectName.geyKeyPropertyList() returns a
rather than a
plain Hashtable (compatibility forbids us from
changing it to Map<String,String>, alas).
And, especially, the methods in the href="">
RelationServiceMBean are much more
understandable with their new generic return types. It was
pretty tough understanding what was in the Map
returned by href=",%20java.lang.String,%20java.lang.String)">
Now that it's a
Map<ObjectName,List<String>> you have
a fighting chance of making sense of it.

One nice effect of generification is that you no longer need a
cast in the following assignment:

SomeMBean proxy = (SomeMBean)
    mbeanServer, objectName, SomeMBean.class, false);

As a side-note, this can now be replaced by the much

SomeMBean proxy =
    JMX.newMBeanProxy(mbeanServer, objectName, SomeMBean.class);

More powerful wildcards in ObjectName

class has always had support for
wildcards, to define ObjectName patterns. But
you could not use a wildcard within the value of a key. For
example, you could not write
domain:type=Dir,path="/foo/bar/*" to match an
ObjectName such as
domain:type=Dir,path="/foo/bar/baz" but not
domain:type=Dir,path="/fred/jim/sheila". Now you

ObjectName implements Comparable

ObjectName is now Comparable. The
ordering function is a little arbitrary, but the important point
here is that you can take a collection of
ObjectNames, such as the result of
, and put them in a
to see them in a more meaningful
order. For example, if I write this...

MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
Set<ObjectName> names = mbs.queryNames(null, null);
System.out.println(names.toString().replace(", ",

...then I'll get this rather random output:

java.lang:type=MemoryPool,name=Eden Space
java.lang:type=MemoryPool,name=Survivor Space
java.lang:type=MemoryPool,name=Code Cache
java.lang:type=MemoryPool,name=Tenured Gen
java.lang:type=MemoryPool,name=Perm Gen

On the other hand, if I add the following line after the
assignment to names...

names = new TreeSet(names);  // a TreeSet is a SortedSet

...then I get this reasonable ordering:

java.lang:type=MemoryPool,name=Code Cache
java.lang:type=MemoryPool,name=Eden Space
java.lang:type=MemoryPool,name=Perm Gen
java.lang:type=MemoryPool,name=Survivor Space
java.lang:type=MemoryPool,name=Tenured Gen


NotificationBroadcasterSupport constructor with MBeanInfo[]

If you have an MBean that emits notifications, it must
implement the
interface. The JMX
API provides a default implementation called
. But you are
supposed to override the
method to return an array
of all the notification types you might send. Since this
array is almost always a constant,
NotificationBroadcasterSupport now has a

that allows you to supply the array and avoid
having to override getNotificationInfo().

New StandardEmitterMBean class

Speaking of MBeans that emit notifications, if you're writing a
Standard MBean but you can't subclass
NotificationBroadcasterSupport because you have
already need to inherit from a different parent class, you can
use the new
class to build a
notification-emitting MBean from your Standard MBean class. You
can also use this class if you need to customize the behaviour
of a notification-emitting Standard MBean, for example to change
the contents of its MBeanInfo.

New Query.isInstanceOf

You can now query for MBeans that are an instance of a
particular class or interface. For example, to find all Monitor
MBeans in the domesne domain, you could write:

QueryExp isMonitor =
Set<ObjectName> monitorNames =
    mbeanServer.queryNames(new ObjectName("domesne:*"), isMonitor);

Actually, I should warn you that this will change after the
Beta, and the first line will become this instead:

QueryExp isMonitor =

Alert readers will deduce that either I was lying when I said
there would be no significant API changes after the Beta, or I
don't consider this a significant change. Either way, this is
likely to be about as significant as it will get.

Monitor Service supports complex types

Previously, the Monitor Service defined by
could only monitor
attributes of simple numeric types like int or
double, or strings. (A reminder that this
service allows you to sample an attribute periodically and
send a notification if it goes over or under a certain
threshold.) Now, you can monitor a value inside a complex
type using a syntax like

The ability to pick out values like this is confined to the
Monitor Service. You cannot call
to obtain a similar effect. (We thought about allowing that,
but it could pose problems for existing code that uses
attribute.names.with.dots and it's also not obvious
what the corresponding behaviour for setAttribute
should be.)

Address of a JMXConnector

If you have an RMI connector client obtained with code
something like this...

JMXServiceURL jurl =
    new JMXServiceURL("service:jmx:rmi://blah);
JMXConnector jc = JMXConnectorFactory.connect(jurl);

...then you can now retrieve the address from jc
like this...

JMXServiceURL jurl2 = ((JMXAddressable) jc).getAddress();

Here, jurl2 will be equal to

So there it is

As usual, if you have comments on these new features or the way
they are specified, feel free to drop me a line at href="">

Related Topics >>