Java Dynamic Management Kit 5.0 Tutorial

Chapter 5 MBean Server in a Minimal Agent

An agent application is a program written in the Java language that contains an MBean server and a means of accessing its functionality. This would be a minimal agent, anything less could not be managed. In our example of a minimal agent, we will access the MBean server through the HTML protocol adaptor from a web browser.

In a real management solution, the agent could be instantiated and loaded with MBeans for all services and resources that it might need when started. However, a minimal agent might also be used when resources and services are unknown at the time when it is launched. They would be instantiated dynamically at a later date by some management application connected to the agent. This flexibility shows how the Java Dynamic Management Kit (DMK) lets you develop many different management solutions, depending on your intended deployment strategy.

For now we will focus on the functionality of the MBean server and how to interact with it through the HTML protocol adaptor. The code samples in this chapter are from the files in the MinimalAgent example directory located in the main examplesDir (see “Directories and Classpath” in the Preface).

This chapter covers the following topics:

MBean Server Classes

Before writing an agent application, it is important to understand the functionality of the MBean server. It is actually an interface and a factory object defined by the agent specification level of the JMX specification. The Java DMK provides an implementation of this interface and factory. The factory object finds or creates the MBean server instance, making it possible to substitute different implementations of the MBean server.

MBeanServer Interface

The specification of the interface defines all operations that can be applied to resources and other agent objects through the MBean server. Its methods can be divided into three main groups:

MBean Server Implementation and Factory

The MBeanServerImpl class in the Java DMK implements the MBeanServer interface. It is the class that will be instantiated in an agent. However, it is never instantiated directly by the agent application. Instead, you rely on the MBean server factory to return a new instance of the implementing class.

The MBeanServerFactory is a static class defined by the JMX specification that makes the agent application independent of the MBean server implementation. It resides in the Java virtual machine and centralizes all MBean server instantiation. The MBeanServerFactory class provides two static methods:

You must use this class to create an MBean server so that other objects can obtain its reference by calling the findMBeanServer method. This method enables dynamically loaded objects to find the MBean server in an agent that has already been started.

Minimal Agent

The minimal agent contains only the essential components of a complete agent application. These are:

Example 5–1 shows the complete application from the MinimalAgent.java file:


Example 5–1 Minimal Agent

import javax.management.ObjectInstance;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;

public class MinimalAgent {

    public static void main(String[] args) {
        
        // Instantiate the MBean server
        System.out.println("\nCreate the MBean server");
        MBeanServer server = MBeanServerFactory.createMBeanServer();
        
        // Create and start some way of communicating:
        //    - an HTML protocol adaptor
        //    - an HTTP connector server
        //    - an RMI connector server
        // Any single one of these would be sufficient
        try {

            System.out.println(
                "\nCreate and start an HTML protocol adaptor");
				ObjectInstance html = 
		server.createMBean("com.sun.jdmk.comm.HtmlAdaptorServer", 
					  null);
            server.invoke(html.getObjectName(), "start",
                          new Object[0], new String[0]);

            System.out.println(
                "\nCreate and start an HTTP connector server");
            ObjectInstance http = server.createMBean(
				"com.sun.jdmk.comm.HttpConnectorServer", 
					  null);
            server.invoke(http.getObjectName(), "start",
                          new Object[0], new String[0]);

            System.out.println(
                "\nCreate and start an RMI connector server");
            ObjectInstance rmi = server.createMBean(
                "com.sun.jdmk.comm.RmiConnectorServer", 
					  null);
            server.invoke(rmi.getObjectName(), "start",
                          new Object[0], new String[0]);

        } catch(Exception e) {
            e.printStackTrace();
            return;
        }

        System.out.println(
"\nNow, you can point your browser to http://localhost:8082/");
        System.out.println(
"or start your management application to connect to this agent.\n");

    }
}

One of the most important lines of code in this example is the instantiation of the MBean server:

MBeanServer server = MBeanServerFactory.createMBeanServer();

The MBean server is created through the static MBeanServerFactory object, and we store its object reference. Its true type is hidden by the factory object, that casts the returned object as an MBeanServer interface. The MBean server is the only functional class referenced directly in this application.

Then we just need some means of communicating (only the HTML adaptor is shown here):

ObjectInstance html = 
server.createMBean("com.sun.jdmk.comm.HtmlAdaptorServer", null);
server.invoke(html.getObjectName(), "start", new Object[0], new String[0]);

For each of the communications protocols we ask the MBean server to create the corresponding MBean. We must provide the class name of the MBean that we want the MBean server to instantiate. The MBean server instantiates the object, registers it for management, and returns its ObjectInstance reference (see ObjectInstance of an MBean).

When an MBean is created through the MBean server, you can never obtain a direct programmatic reference on an MBean. The object instance is the only handle the calling process has on the MBean. The MBean server hides the MBean object instance and only exposes its management interface.

We then ask the server to invoke the start operation of the HTML adaptor's MBean. The object instance gives us the MBean's object name which we use to identify the MBean (see Object Names). The other parameters correspond to the signature of the start operation, which takes no parameters. This operation activates the adaptor or connector so that it will respond to remote management operations on its default port. We can now connect to the HTML protocol adaptor from a web browser.

Referencing MBeans

As demonstrated by the minimal agent, most agent applications interact with MBeans through the MBean server. It is possible for an object to instantiate an MBean class itself, which it can then register in the MBean server. In this case, it keeps a programmatic reference to the MBean instance. All other objects can only interact with the MBean through its management interface exposed by the MBean server.

In particular, service MBeans and connectivity MBeans rely solely on the MBean server to access resources. The MBean server centralizes the access to all MBeans. It unburdens all other objects from having to keep numerous object references. To ensure this function, the MBean server relies on object names to identify MBean instances uniquely.

Object Names

Each MBean object registered in the MBean server is identified by an object name. The same MBean class can have multiple instances, but each must have a unique name. The ObjectName class encapsulates an object name composed of a domain name and a set of key properties. The object name can be represented as a string in the following format:

DomainName:property=value[,property2=value2]*

The DomainName, the property and value can be any alphanumeric string, as long as it does not contain any of the following characters: : , = * ?. All elements of the object name are treated as literal strings, meaning that they are case sensitive.

Domains

A domain is an abstract category that can be used to group MBeans arbitrarily. The MBean server lets you search easily for all MBeans with the same domain. For example, all connectivity MBeans in the minimal server could have been registered into a domain called Communications.

Since all object names must have a domain, the MBeans in an MBean server necessarily define at least one domain. When the domain name is not important, the MBean server provides a default domain name that you can use. By default, it is called the DefaultDomain, but you can specify a different default domain name when creating the MBean server from its factory.

Key Properties

A key is a property-value pair that can also have any meaning that you assign to it. An object name must have at least one key. Keys and their values are independent of the MBean's attributes. The object name is a static identifier that identifies the MBean, whereas attributes are the exposed, runtime values of the corresponding resource. Keys are not positional and can be given in any order to identify an MBean.

Keys provide the specificity for identifying a unique MBean instance. For example, an object name for the HTML protocol adaptor MBean might be: Communications:protocol=html,port=8082, assuming the port will not change.

Usage

All MBeans must be given an object name that is unique. It can be assigned by the MBean's preregistration method, if the MBean supports preregistration (see the Javadoc API of the MBeanRegistration interface). Or it can be assigned by the object that creates or registers the MBean, which overrides the one given during preregistration. However, if neither of these assign an object name, the MBean server will not create the MBean and will raise an exception. Once an MBean is instantiated and registered, its assigned object name cannot be modified.

You can encode any meaning into the domain and key strings. The MBean server handles them as literal strings. The contents of the object name should be determined by your management needs. Keys can be meaningless serial numbers if MBeans are always handled programmatically. On the other hand, the keys can be human-readable to simplify their translation to the graphical user interface of a management application. With the HTML protocol adaptor, object names are displayed directly to the user.

ObjectInstance of an MBean

An object instance represents the complete reference of an MBean in the MBean server. It contains the MBean's object name and its Java class name. Object instances are returned by the MBean server when an MBean is created or in response to queries about MBeans. Since the object name and class name cannot change over the life of a given MBean, its returned object instance will always have the same value.

You cannot modify the class or object name in an object instance. This information is read-only. The object name is used to refer to the MBean instance in any management operation through the MBean server. The class name can be used to instantiate similar MBeans or introspect characteristics of the class.

Minimalist Agent

Example 5–2 gives the code for one of the smallest agents you can write. It retains all the functionality that we will need to connect to it with a web browser described in Chapter 6, HTML Protocol Adaptor.


Example 5–2 Minimalist Agent

import javax.management.ObjectInstance;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;

public class MinimalistAgent {

    public static void main(String[] args) {
        
        MBeanServer server = MBeanServerFactory.createMBeanServer();
        
        try {

            ObjectInstance html = server.createMBean(
                "com.sun.jdmk.comm.HtmlAdaptorServer", null);
            server.invoke(html.getObjectName(), "start", null, null);

        } catch(Exception e) {
            e.printStackTrace();
            return;
        }
    }
}


Note –

Only three classes are “imported” by this program and needed to compile it. However, the MBean server dynamically instantiates other classes, such as the HtmlAdaptorServer, that are needed at runtime. As a result, the Java DMK runtime JAR files (jdmkrt.jar and jsnmpapi.jar) must be in the classpath of the Java virtual machine that is running the minimal agent (see “Directories and Classpath” in the Preface).


The MinimalistAgent relies on the HTML adaptor, but we could have used any MBean that provides some way of accessing the MBean server. You could even use your own MBean that encodes some proprietary protocol, provided it makes all functionality of the MBean server available remotely.

It is important to realize that this minimalist agent is a fully functional agent that is every bit as powerful as any agent that can be deployed. Because we can connect to this agent, we can dynamically create new MBeans for it to manage, and classes that are not available locally can be downloaded from the network (see Chapter 14, M-Let Class Loader). Because resources, services, and other connections can be added dynamically, this agent can participate in any management scheme.

Of course, it is more efficient for the agent application to perform the initialization, including the creation of all MBeans that are known to be necessary. Typically, an agent application also needs to set up data structures or start specific applications that its resources require. For example, it can establish a database session that an MBean will use to expose stored information. The agent application usually includes everything necessary for making the intended resources ready to be managed within the intended management solution.

However, there is no single management solution. Many different agent applications can perform the same management function, requiring more or less intervention after they are started. And the flexibility of the Java DMK enables many different management solutions to achieve the same goal. For example, an MBean could also establish the database session itself during its preregistration phase.

Running the Minimal Agent Example

The example code for the MinimalAgent application is located in the examplesDir/MinimalAgent directory. This agent application only has minimal output and is intended to be accessed for management through one of its communication MBeans. However, you will need to compile and start the minimal agent before continuing on to the next chapter.

To Run the Minimal Agent Example
  1. Compile the MinimalAgent.java file in the examplesDir/MinimalAgent directory with the javac command.

    For example, on the Solaris platform, type:


    $ cd examplesDir/MinimalAgent/
    $ javac -classpath classpath *.java
    

    When we access the minimal agent through the HTML adaptor, we will instantiate the SimpleStandard and SimpleDynamic classes. Because we do not use a dynamic class loader, the agent will need these classes at runtime. You must compile the standard and dynamic MBean classes as described in Running the Standard MBean Example and Running the Dynamic MBean Example.

  2. To run the example, update your classpath to find the MBeans and start the agent class:


    $ java -classpath classpath:../StandardMBean:../DynamicMBean MinimalAgent
    

Because this is a minimal agent, the example does not have much output. The MBean server is started, and the three communication MBeans are created. It is now possible to connect to this agent. Management applications can connect through the HTTP and RMI connector servers, as described in Connector Servers.

The simplest way to communicate with the agent is through the HTML protocol adaptor. This adaptor provides a view of the agent and its MBeans through standard HTML pages that can be viewed on almost any web browser.

To connect to the agent, load the following URL in your browser:

If you get an error, you might have to switch off proxies in your preference settings or substitute your host name for localhost. Any browser on your local network can also connect to this agent by using your host name in this URL. Chapter 6, HTML Protocol Adaptor details how to manage this agent from its web view.