Java Management Extensions (JMX) Motivation & API Survey
S V Ramu (2002-02-24, 2002-03-07)
This article is better studied as your first exposure to JMX, but should definitely be accompanied by JMX spec and javadocs. But some aspects of the article is useful, in retrospection, than as a prelude. So you just have to skip between this article, the spec and the javadocs. Defeats the purpose? Do try as a prelude first.
What is JMX?
JMX, Java Management Extension, is an API (set of commonly accepted Classes and Interfaces) for managing. Managing what? The idea is to manage any devices or applications, which has a wrapper conforming to the specification as defined in JMX standard. In much simpler terms, if you want something (any device or application) to be managed in the JMX model, you have to implement few interfaces, or follow some JavaBean like naming patterns. After this you might be registering it with some JMX implementations. Then, you can write an application which can query the JMX Server (or some such thing) and talk to it in a standard way. But how can you control different devices and applications with a just one api? Won't each device have their own controls, indicators, and signals?
The JMX model
A device is a nice simile for a JMX enabled resource. Of course even an application could be one (JBoss is the foremost example). A managed resource is provided an interface by JMX. All resources to be managed are abstracted as Attributes (indicators? maybe a modifiable indicator), Operations (Controls), Notifications (output signals), and some Descriptors. Also Constructors.
In a sense, JMX is just a glorified and abstracted Reflection. Where Attributes are like Variables, Operations are like Methods/Procedures, Notifications are like Events, and Descriptors are just Name-Value pairs. The resource that is willing to be managed, exposes a set of Attributes, Operations and Notifications, to a central server, and thus being transparent to the managing applications, otherwise.
Though much of the JMX API is concentrating on the reflection-like part alone, some other parts are concerned with abstracting variables which perform the activities like counters, gauges (analog-ish), and Strings comparators. Apart from this, there are classes for time (or period) triggers, and for specifying the relation between various management adapters.
The MBean is the central concept for this whole api, although there is no class or Interface called MBean as such. Any class that we write (say, MyClass), implementing an interface (MyClassMBean), either with same name suffixed with MBean, or DynamicMBean is considered an MBean. Thus MBean is the wrapper that we write for making a resource a manageable entity. MBean is the one, which is said to be containing the Attribute, Operations and Notifications (that AON). Of these Attribute and Operation are fully defined by the MBean suffixed interfaces (either DynamicMBean or <ClassName>MBean, which is called Standard MBean). The Notifications are exposed by the NotificationBroadcaster interface. There are two more types of DynamicBeans. They are Dynamic Beans becuase they too implement DynamicBean interface, but have additional restrictions, to aid some automatic processing by the central server (MBean Server). There are two types of special dynamic MBeans. One is called Open MBeans and the other is Model MBean. Both are just a way to create or declare a MBean out of nowhere. Of these, Open MBean is not yet fully standardized (not mandatory for the JMX service providers), and hence is not a part of the Javadocs. The spec says,
...Concepts and classes of open MBeans presented in this chapter are still subject to change. Hence, compliance to open MBeans is not required, and in fact, compliance to open MBeans is impossible to claim in this phase of the specification. Open MBeans are intended to be fully defined and to become mandatory in the next release.
The Glorified Reflection
In a way JMX treats any MBean (just a special wrapper class for a thing we want to measure) as having Attributes, performing some Operations and emitting some Notifications. This in a way is a form of reflection. In fact, the Standard MBean is identified purely by reflection. The term used for this process of finding whether a class is Standard MBean, or DynamicMBean, or Open MBean or a Model MBean is (poetically) called as Introspection. So, JMX introspects using reflection!
How would you define an Attribute of a MBean? Ask, what is a Attribute for a class (because a MBean is a class). The JavaBean model lends a hand here, and hence, any JavaBean style getter and setter together constitute an Attribute (hence you can imagine read-only or write only attributes). Of course one more condition is that, these methods should be there in the <ClassName>MBean interface. This type of attribute declaration is for the Standard-MBean. For Dynamic-MBeans, the two methods Object DynamicMbean.g(s)etAttribute(String attribute) acts as the generic getters and setters for Attributes. The Operations are overly simplified by one method, Object DynamicMbean.invoke(String actionName, Object params, String signature) to act as any general Java Method (procedure or a function). As you would have guessed the actionName is the method name, and params are its parameters. Obviously no parameter can be a primitive type. But what is this signature for? In the specification words,
By including the operation signature, the dynamic MBean implementation may verify that the mapping is consistent between the requested operation and that which is exposed.
It seems that this is an attempt to offset the non-availability of type checking due to this highly flexible definition of a Java method. As always, type checking is the cost we pay for abstraction and flexibility that we get. But does this requirement of having signature (the class type) needed? I doubt it, because the rising of Exception for mismatch of parameters is anyway done by the actual invocation. (Any special situation in question? Oh yeah! How else the server can resolve between two operations with the same name but different signatures, in case of overloaded methods? No! even then, the number of params and their types known by reflection, can do the job; so we don't need signature?).
Notification, in the spirit of the Swing event model, is realized through Listeners. A MBean is considered to have Notifications, if and only if it implements the NotificationBroadcastor interface, which just adds and removes NotificationListeners and Filters (for being choosy about the Notifications to listen for). It also exposes the list of Notifications through MBeanNotificationInfo getNotificationInfo() method, which is what is used by the MBean Server to provide for the managing applications. Both Standard-MBean and the Dynamic-MBean need to implement this interface for exposing Notifications. Curiously,
Any type of MBean may implement the NotificationBroadcaster interface. This may lead to a special case of a standard MBean, which has an empty management interface: its role as a manageable resource is to be a broadcaster of notifications. It must be a concrete class with a public constructor, and it must implement an MBean interface, which in this case defines no methods. The only methods in its class are those implementing the NotificationBroadcaster interface. This MBean may be registered in a JMX agent, and its management interface only contains the list of notifications that it may send.
Notification uses a partial Memento (GoF) pattern, to aid in the proper resolution of the Notification received by the NotificationListeners. You have to not only give the NotificationListener and Filters to, void NotificationBroadcaster.addNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback) but also
An opaque handback object to be sent back to the listener when a notification is emitted. This object cannot be used by the Notification broadcaster object. It should be resent unchanged with the notification to the listener.
void handleNotification(Notification notification, Object handback)
An opaque object which helps the listener to associate information regarding the MBean emitter. This object is passed to the MBean during the addListener call and resent, without modification, to the listener. The MBean object should not use or modify the object.
I call this partial Memento in the sense that the Broadcaster (Caretaker) is not at all using the handback (Memento) in any form whatsoever, but to keep it as an opaque object to be given back.
Apart from AON, we also have constructors, which completes the correspondence of an MBean with any class.
An MBean may have any number of constructors, provided at least one is declared public, in order to allow an agent to do an instantiation. An MBean may also have any number of public constructors, all of which are available to a management application through a JMX agent which can instantiate this MBean class.
For now, there are 6 packages (few more are on cards for the next release). The classes and interfaces follow a highly OOed design, where anything and everything is an object. 16 Interfaces, 35 Classes and 16 Exceptions. Have ever wondered of using extreme OO where you express even the smallest thing as a class? How about expressions like say, (bingo+3*ding/6-1) or some such things?! Try, the set of classes/interfaces with Query/Value in its name. Monitoring MBeans: In the composite pattern spirit, the MBean monitor itself is a MBean!
For the fear of being a photo copy of the well-written specs, I'm only giving my views and understanding of the API, along with some interesting or crucial snippets from the original. The key goal is to wear the hat of the JMX designers, and thus provide the motivations behind the classes and methods. For all useful details, you have to consult the pdf spec and the accompanying html javadocs. Of course, if my experience is any indicator, thinking in the above lines will help you in fully appreciating the meticulous wordings of the spec itself. While studying the specs, do remember few terminologies,
Instrumentation level: This basic level which provides a specification for implementing JMX manageable resources. A JMX manageable resource can be an application, an implementation of a service, a device, a user, and so forth. It is developed in Java, or at least offers a Java wrapper, and has been instrumented so that it can be managed by JMX-compliant applications. The instrumentation of a given resource is provided by one or more Managed Beans, or MBeans, which are either standard or dynamic.
Agent level: Provides a specification for implementing agents. Management agents directly control the resources and make them available to remote management applications. Agents are usually located on the same machine as the resources they control, although this is not a requirement. This level builds upon and makes use of the instrumentation level, in order to define a standardized agent to manage JMX manageable resources. The JMX agent consists of an MBean server and a set of services for handling MBeans. In addition, a JMX agent will need at least one communications adaptor or connector, but these are not specified in this phase. The MBean server implementation and the agent services are mandatory in an implementation of the specification.
Distributed Services level: Provides the interfaces for implementing JMX managers. This level defines management interfaces and components that can operate on agents or hierarchies of agents.
As far a I have seen, the spec is really very lean in its content, and hence highly recommended for any distributed nexus between any two modules of an application, like in JBoss,
Our goal is to provide the full J2EE stack in the free/open world. We are already there and the reason for our success lies on JMX. JMX or Java Management eXtension is the best weapon we have found for integration of software. It provides a common spine in which we plug in modules, containers and plugins (JTS/JTA, Security, Data Sources, Remote Management, EJB, DBs, JSP and JMS). While we provide JBoss implementations for many of these services you are free to include your favorite implementation in the JMX enabled base and therefore "dropping" your own transaction or persistence service in JBoss, all dynamically.
Marc Fluery of JBoss has rightly pointed out that,
Then we really surprised the industry when we introduced Java Management eXtensions (JMX) as the base of our servers. Others, mostly BEA, have been quick to adopt this SUN standard but not as profoundly and un-conventionally as we did. They use it, for "management;" we use it as the standard base for our modularity and a clear, clean way to load, startup, configure and also manage all of our server. We introduced this a year and a half ago, in early 2000, and the rest of the industry is still scratching their heads to figure out what this really means. Some follow suit, (BEA/IBM), others just give up. But we keep on trail blazing tech-wise.
This is a well written complete document, as all spec docs are, but bit intolerable, if you do not know the forces behind JMX as such. Even few terminologies are alienating, if you miss the motivation behind the whole area. Otherwise, it is indispensable for both JMX users and implementers. You would be downloading a Reference Implementation along with javadocs and this pdf doc. My way of overcoming the initial hurdle would be to analyze the spirit of the classes and interfaces, through the accompanying javadoc, try too get a rough picture of things, then round it all off with the spec pdf. Of course, if you could try your hands with the installation and examples, nothing like it.
I haven't tried its docs fully, but JBoss is supposed to be using JMX extensively. Since their claim is that their whole app server is just a collection of JMX plugins (EJB, JMS etc.) to the central small implementation of JMX ('Super Server'), it would be a nice goal to see through their source code for JBoss 3.0 alpha. ('RabitHole' - Like in the film MATRIX, it seems! See it, and there is no turning back.)