|
|
|||||||||||||||||
Eamonn McManus's BlogCommunity: Java Communications ArchivesDefining MBeans with annotationsPosted by emcmanus on August 31, 2007 at 08:11 AM | Permalink | Comments (9)The number one question I get about the JMX API at conferences and other public events is whether there will be support for defining MBeans using annotations. People see that they can make EJBs or Web Services just by adding annotations to a POJO, and they ask why they can't make MBeans the same way. In version 2.0 of the JMX API, being defined by JSR 255, this will be possible. The exact details are still subject to change as a result of discussions within the JSR 255 Expert Group, but here's a snapshot of where we are now. I think the final version will be fairly close to this. In addition to defining MBeans with annotations, there are some new proposed annotations that will also apply to MBeans defined in the existing ways. Prior artSeveral projects already exist that provide this functionality, but the most developed is probably Spring. So our starting point was Spring's MBean annotations (see also API documentation). Defining an MBeanIn the proposed design, an MBean can be defined through annotations to achieve the same effect as a Standard MBean. In this and other examples, I'll show what you write with today's API, and what you'll be able to write with the new annotations.
This defines an MBean with read-only attribute I'll call an MBean defined this way an @MBean. One way to look at this is that with the existing Standard MBeans,
public methods from the class are picked out as being management
methods by virtue of being in the Standard MBean interface that
the class implements. So in this example the
Pros and cons of @MBeansThe new style appears considerably more convenient than Standard MBeans. You only have to maintain one source file, rather than managing a class and an interface. There is a downside, however, which may show up in bigger projects. The advantage of the Standard MBean approach is that the MBean interface tells you exactly what the attributes and operations of the MBean are. There is no extraneous information in the MBean interface: every method defines an attribute or an operation. On the other hand, with @MBeans the management attributes and operations are potentially mixed in with many other methods, public or private. So it is not immediately obvious what the management interface of the MBean is. This disadvantage applies both when reading the source code and when looking at the Javadoc output. A second disadvantage is that it is no longer possible to construct a proxy. Proxies simplify client code by allowing it to access attributes and operations as compiler-checked method calls. They don't matter if you are only going to interact with your MBeans through a graphical interface like JConsole, but they are a big help if you are writing an application that will interact with your MBeans specifically. For smallish projects, these disadvantages are likely to be
minor. Furthermore, it should be possible to define an annotation
processor that extracts a Standard MBean interface from an
@MBean, so it can be used for documentation and proxying. In
the example above, the annotation processor could create the
Defining an MXBeanThe existing @MXBean
public class Cache {
...remainder as above...
}
DescriptionsAlthough the JMX API allows for textual descriptions to be associated with attributes, operations, and parameters, when you use a Standard MBean today these descriptions have meaningless default values. I've written before about how you can add meaningful descriptions, but it isn't easy. This is a really obvious use for annotations. The proposed new
We international types will of course be thinking about internationalization, and I'll have more to say about that below. Finding the MBeanServer and/or ObjectNameOften an MBean needs to know what MBean Server it is registered
in, or what its name is in that MBean Server. To do this it
currently needs to implement the In the new proposal, the
When the MBean is registered, the MBean Server will inject the appropriate values into these fields. This possibility is open to all types of MBeans, not just
@MBeans. You could continue to have a Standard MBean as today,
but stop implementing Simplified notification handlingToday, if an MBean emits notifications then it must implement
the In practice, everybody uses the New annotations allow you to define the list of notification types more simply, and to emit notifications without having to keep track of listeners.
The The new Resource injection of More detail than you want to know about
You can stop reading nowIf your eyes are already glazing over with all this code, you can safely stop here, and you'll have seen the main ideas. The remainder of this entry is about secondary items, and further details about the main ones. Descriptor contentsIn the JMX API included in the Java SE 6 platform, we introduced a way to define your own annotations to specify Descriptor contents. So you might define @Units like this: @Documented @Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Units {
@DescriptorKey("units")
String value();
}
The new API accepts such annotations on classes or methods that also have the @ManagedX annotations. For example: @MBean
public class Cache {
...
@Units("bytes")
@ManagedAttribute
public int getUsed() {...}
...
}
We've also added a new @MBean
public class Cache {
...
@DescriptorFields("units=bytes")
@ManagedAttribute
public int getUsed() {...}
...
}
This annotation can be used in Standard MBeans and MXBeans as well as @MBeans and @MXBeans. Operation impactThe @MBean
public class Cache {
...
@ManagedOperation(impact = Impact.ACTION)
public int dropOldest(int n) {...}
}
You can also apply MBean constructorsEach public constructor in an @MBean or @MXBean is converted into an
StandardMBean classThe class Details on Resource injectionThe @Resource // field injection
private volatile ObjectName name;
private MBeanServer mbs;
@Resource // method injection
private synchronized void setMBeanServer(MBeanServer mbs) {
this.mbs = mbs;
}
The MBean Server determines what to inject based on the
type. The type is either the declared type of the field or
parameter, or it is specified explicitly in the
@Resource
private volatile ObjectName name;
@Resource(type = ObjectName.class)
private volatile Object name;
I don't think the second form will be used very often, but it might
be used to inject the The ObjectName (etc) will be injected as many times as there are
appropriate
I've used Resource injection happens after the MBean's More on descriptionsIn addition to the description text, the @Description(value="some sort of cache",
key="cache.mbean.description",
bundleBaseName="MyResources")
To complete the story here, we need to have something that is
able to apply these Descriptor fields to localize the
More on @NotificationInfoAs I threatened, here is more information than you wanted to
know about If an MBean has a @NotificationInfo(types = {AttributeChangeNotification.ATTRIBUTE_CHANGE},
notificationClass = AttributeChangeNotification.class)
If the MBean can emit more than one class of MBean, then it can
use @NotificationInfos(
@NotificationInfo(types = {"my.first.notif", "my.second.notif"})
@NotificationInfo(types = {AttributeChangeNotification.ATTRIBUTE_CHANGE},
notificationClass = AttributeChangeNotification.class)
)
The This is why there is an optional element of type
@NotificationInfo(types={"my.notif.type"},
description=@Description(value="my notification", key="my.notif.descr"))
You cannot use @NotificationInfo(types={"my.notif.type"},
descriptorFields={"foo=bar"})
Ideas still in progressWe're studying the possibility of providing a way to cause a notification that is sent every time a given operation is completed. We're looking at ways in which an MBean could say what its What next?This is still work in progress, as you'll have gathered. I'm
very much interested in comments and suggestions, either here or
at [Tags: jmx jsr jsr255 annotations] | |||||||||||||||||
|
|