Java Dynamic Management Kit 4.1 Tutorial

M-Let Loading from a Manager (JDK1.1)

Like the other agent services of the Java Dynamic Management Kit, the m-let loader is an MBean and fully manageable from a remote manager. A manager application might want an agent to load a new MBean to represent a new resource or provide a new management service. In this example, we show a manager which interacts with the m-let loader of an agent to load exactly the same MBeans as in the previous example.

The agent that we will manage only contains an RMI connector and an HTML adaptor when it is launched. We will use the RMI connector to access the agent and perform all of our management operations. You can then view the new MBeans through the HTML adaptor.

The manager is just a simple application which creates its connector client, does its management operations and exits. Here is the code of its main method and the constructor that it calls.


Example 8-5 The main Method of the M-Let Manager

public Client() {
    
    // Enable the trace mechanism
    [...]

    // Connect a new RMI connector client to the agent
    connectorClient = new RmiConnectorClient();

    // Use the default address (localhost)
    RmiConnectorAddress address = new RmiConnectorAddress();
    try {
        connectorClient.connect(address);
    } catch (Exception e) {
        echo("Could not connect to the agent!");
        e.printStackTrace();
        System.exit(1);
    }
}

public static void main(String[] args) {

    // Parse command line arguments.
    [...]

    // Call the constructor to establish the connection
    Client client = new Client();

    // Run the MLet example (see below)
    client.runMLetExample();

    // Disconnect connector client from the connector server.
    client.connectorClient.disconnect();

    System.exit(0);
}

Asking the Agent to Load Classes

Now that the manager is connected to the client, we can "push" classes to it. We do this by first creating an m-let loader service, then having that loader create MBeans from the classes designated by our HTML file. The following code is taken from manager's runMLetExample method. The code is identical to the code of the agent example, except that we now go through the RemoteMBeanServer interface of the connector client instead of directly through the MBean server.


Example 8-6 Calling the performLoadURL Method Remotely

// Get the domain name from the Agent
String domain = connectorClient.getDefaultDomain();

// Create a new MLetSrv MBean and add it to the Agent
String mletClass = "javax.management.loading.MLetSrv";
ObjectName mletName = new ObjectName(domain + ":name=" + mletClass);
connectorClient.createMBean(mletClass, mletName);
[...]

// Create and register new Square and EquilateralTriangle MBeans
// by means of an HTML document containing MLET tags
// The url string is read from the command line
ObjectName squareMLetClassLoader = null;
ObjectName triangleMLetClassLoader = null;

Object mletParams[] = {url};
String mletSignature[] = {"java.lang.String"};
Vector mbeanList = (Vector) connectorClient.invoke(
    mletName, "performLoadURL", mletParams, mletSignature);

for (Enumeration enum = mbeanList.elements(); enum.hasMoreElements(); ) {
    Object element = enum.nextElement();
    if (element instanceof Vector) {
        // Success, we retrieve the new object name
        Vector v = (Vector) element;
        ObjectInstance objectInstance = (ObjectInstance) v.elementAt(0);
        ObjectName classLoaderObjectName = (ObjectName) v.elementAt(1);
        if (objectInstance.getClassName().equals("Square")) {
            // Retrieve the MBean that loaded the Square

            squareMLetClassLoader = classLoaderObjectName;
        } else if (objectInstance.getClassName().equals(
                       "EquilateralTriangle")) {
            // Retrieve the MBean that loaded the EquilateralTriangle
            triangleMLetClassLoader = classLoaderObjectName;
        }
        echo("\tOBJECT NAME = " + objectInstance.getObjectName());
    } else {
        // Failure, find out why
        echo("\tEXCEPTION = " + ((Throwable)element).getMessage());
    }
}

As in the agent application, we may need a shortcut for instantiating other MBeans without specifying an m-let file. Again, we can use an existing class loader from a previously loaded class to download the same classes again. We use the createMBean method of the connector client which lets us specify a class loader name. The following code is the rest of the manager's runMLetExample method, and it is also nearly identical to the agent's code.


Example 8-7 Asking the Agent to Load Classes Directly

// Create a new Square MBean from its class in the Square.jar file.
String squareClass = "Square";
ObjectName squareName = new ObjectName(
    "MLetExample:name=" + squareClass + ",id=2");
Object squareParams[] = {new Integer(12)};
String squareSignature[] = {"java.lang.Integer"};
connectorClient.createMBean(squareClass, squareName,
    squareMLetClassLoader, squareParams, squareSignature);

// Create a new EquilateralTriangle MBean from its class in the
// EquilateralTriangle.jar file.
String triangleClass = "EquilateralTriangle";
ObjectName triangleName = new ObjectName(
    "MLetExample:name=" + triangleClass + ",id=3");
Object triangleParams[] = {new Integer(20)};
String triangleSignature[] = {"java.lang.Integer"};
connectorClient.createMBean(triangleClass, triangleName,
    triangleMLetClassLoader, triangleParams, triangleSignature);

Simulating a "push" of the MBeans in this way is plausible, since the management application can specify a URL where it controls the contents of the HTML file and knows which classes are available.

Running the M-Let Manager Example

The MBeans in the agent and manager (client) examples are identical, and we will set up the example in exactly the same manner.


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

$ jar cf Square.jar Square.class SquareMBean.class
$ rm Square.class SquareMBean.class

$ jar cf EquilateralTriangle.jar EquilateralTriangle.class \
EquilateralTriangleMBean.class
$ rm EquilateralTriangle.class EquilateralTriangleMBean.class

The manager is written to be run on the same host as the agent application. If you wish to run it on a different host, you will need to modify the code for the Client class constructor where the agent address is specified (see Example 8-5). You could place the jar files and the m-let file on a remote machine and specify its new URL as the parameter to the manager application; we run the example with this file in the current directory.

Before launching the manager, you must launch the agent. Here we give commands for launching the applications from the same terminal window running the Korn shell. On the Windows NT platform, you will have to launch each application in a separate window.


$ java -classpath classpath Agent &
$ java -classpath classpath Client file:${PWD}/GeometricShapes.html

In the output of the manager, you can see it create the m-let service MBean, and then ask it to load the HTML file. Finally, we can see the two MBeans that were loaded directly through the class loader shortcut. If you connect to the agent in a web browser at the following URL: http://localhost:8082/ and reload its agent view every time the manager pauses, you can see the MBeans as they are created.

The agent terminates after it disconnects its connector client. When you are finished viewing the agent, type the following commands to stop the agent application:


$ fg
java [...] Agent <Control-C>
^C$