GNU Classpath - javax.management

Provides the core classes for the Java Management Extensions (JMX). This API builds on the notion of Java beans by providing a layer of abstraction between the beans themselves and the method of accessing them. Instead of being accessed directly, management beans or MBeans are usually accessed via a management server (an implementation of the @see MBeanServer interface). Thus, the bean itself may be a simple Java object or it may be something more complicated (for example, the server may map from Java to SNMP). The server may also retrieve the bean from some remote location rather than using a local object.

Management beans are usually used for monitoring and/or configuration of a particular entity. For example, the platform management beans found in the @see java.lang.management package allow the user to obtain information about the operating system, current memory usage, etc. as well as turning on and off certain additional facilities. To this end, an MBean consists of:

- attributes that may be read and/or written to.
- operations which may be performed.
- notifications that may emitted by the bean and listened for by users.

The most common type of management bean is the @see StandardMBean, A standard MBean relies on the naming patterns established by the JavaBeans framework; the value of an attribute `name` is retrieved by an accessor method named `getName` and changed by a mutator method called `setName`. If the mutator is absent, the attribute is read only. Naming is also used to associate the implementation of a bean with its interface; an bean `Person` is assumed to be an implementation of the interface `PersonMBean` (and vice versa). To avoid these naming constraints, the @see StandardMBean class may be used.

## Types of Beans

The @see StandardMBean class is one example of a @see DynamicMBean where the attributes and operations of the bean are provided dynamically via the methods provided. With the @see StandardMBean class, this simply means that the class uses reflection to access the appropriate methods of the bean implementation. In a more complex scenario, the bean's data could be supplied from a file or over the network.

Once we start talking about accessing beans over network and platform boundaries, we run in to the issue of how to deal with the types utilised by these beans. Simple types, such as numbers and strings, are usually fine but more complex types need special treatment. An Open MBean is one that only uses a specific set of types defined in the @see javax.management.openmbean package, allowing both sides of a remote connection to provide this subset of types and thus interact. An @see MXBean goes a stage further, and defines a method whereby a normal Java MBean may become an Open MBean by performing a defined mapping on the types of the bean. For example, a @see java.util.List or @see java.util.Set of a particular type becomes an array of the same type.

## Accessing Beans

Although beans can be accessed like normal objects, the normal way of accessing them is via an @see MBeanServer. This provides the abstraction from the bean's implementation to a set of attributes, operations and notifications. The server identifies each bean via an @see ObjectName. This name is unique to a particular bean and is used to identify the bean when retrieving the value of an attribute or invoking an operation. Essentially, most methods provided by the server are the same as those provided by the @see DynamicMBean interface, except that each takes this additional @link ObjectName parameter to identify the bean being accessed.

The @see MBeanServerFactory keeps track of the current MBean servers in use and allows new ones to be created. A special @see MBeanServer instance, called the platform MBean server, is created when the Java virtual machine is started and a reference to this may be obtained from the @see ManagementFactory using @see ManagementFactory#getPlatformMBeanServer(). This primarily exists for the purpose of creating and registering the platform MBeans, described in @see java.lang.management, which provide access to information about the underlying operating system, memory usage, the behaviour of the garbage collector, etc. but is equally suitable for creating and registering your own beans. Alternatively, a server instance may be obtained from the @see MBeanServerFactory.

A bean obtains an @link ObjectName by registering with the server. This operation can be performed either by passing an existing instance to the @see MBeanServer#registerMBean method or by using the @see MBeanServer#createMBean method to simultaneously create the bean and register it with the server. During the registration process, the bean may perform some arbitrary behaviour if it implements the @link MBeanRegistration interface. The same is true when unregistering a bean.

To actually access the attributes and operations of a bean via the server, we use code like the following:

    // First we obtain the platform MBean server which has the platform MBeans registered
    MBeanServer server = ManagementFactory.getPlatformMBeanServer();
    // We also need the object name of the memory bean so we can address it
    ObjectName name = new ObjectName(ManagementFactory.MEMORY_MXBEAN_NAME);
    // Next we obtain the value of the 'verbose' attribute
    // What actually happens here is that the server invokes the 'isVerbose' method of
    // the MemoryMXBean
    boolean verbose = server.getAttribute(name, "verbose");
    // We can also set the value of verbose.  Again the server is actually performing
    // a setVerbose(val) on the bean but we don't need to know this.
    Attribute attrib = new Attribute("verbose", true);
    server.setAttribute(name, attrib);
    // We can also invoke the 'gc' operation which calls the garbage collector.
    server.invoke(name, "gc", new Object[]{}, new String[]{});

As noted above, the server is simply making basic method calls on the object using reflection. However, the server provides a layer of abstraction which means that something more complicated could actually be going on. The lines above are equally applicable, for example, if `server` is instead an @see MBeanServerConnection connecting us to a distant computer.

This rather hideous code can be simplified back into simple method calls on an object, so that we get the best of both worlds. This is achieved using a MBean proxy:

    MBeanServer server = ManagementFactory.getPlatformMBeanServer();
    ObjectName name = new ObjectName(ManagementFactory.MEMORY_MXBEAN_NAME);
    MemoryMXBean bean = JMX.newMBeanProxy(server, name, MemoryMXBean.class);
    boolean verbose = bean.isVerbose();
    bean.setVerbose(true);
    bean.gc();

See how much simpler the operations are? The proxy handles the task of translating the method calls into appropriate invocations of methods on the server, simplifying the code for the user.

Finally, we have assumed in the code above that the @see ObjectName of the bean is known. If this is not the case, then the server's database can be searched. The @see Query class provides appropriate operators (e.g. boolean (and,or), value comparison (>, <)) for building up relatively complex queries. Once constructed, a query may be passed to either the @see MBeanServer#queryNames or @see MBeanServer#queryMBeans to obtain an appropriate set of @see ObjectName or MBean instances.

## Notifications

MBeans also have the capability to emit events. Beans which do so implement either the @see NotificationBroadcaster or @see NotificationEmitter interface (the difference between the two is simply the existence of a better removal method in the newer @see NotificationEmitter interface, which otherwise extends @see NotificationBroadcaster), usually by extending the @see NotificationBroadcasterSupport class. As is usual with event handling, other classes may signup to receive events via the @see NotificationListener interface. The signup process can include registering a filter (an implementation of @see NotificationFilter) so that only certain events reach the listener and others are discarded.

## Remote Access

The subpackage @see javax.management.remote provides facilities to access remote MBean servers. This consists of a connector framework which abstracts the method of accessing remote servers from the actual implementation, so that the same method is used to connect to a remote server, regardless of how it is accessed.