Java Dynamic Management Kit 5.0 Tutorial

M-Let Loading From a Manager

Because the MLet class is an MBean, the m-let loader service is fully manageable from a remote manager. This lets a manager create an m-let loader in an agent, add URLs to its list of code-bases, and create MBeans whose classes must be downloaded first.

Using the m-let class loader, we can again implement a “push” mechanism originating from a management application. In fact, it is even easier due to the direct class loading that the MLet MBean allows.

In the example, our manager will create an m-let loader in an agent and have it load new MBean classes. Started with only an RMI connector and an HTML adaptor, we can see at the end that the agent contains all of the new MBeans loaded from JAR files, along with the m-let loader MBean. The initialization of the manager is very simple:


Example 14–6 main Method of the Manager Application

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 ask it to load classes. First we have it create an m-let loader MBean that we can use to download classes. Then we demonstrate the various ways of loading classes:

The following code is from the 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 14–7 Calling the getMBeansFromURL Method Remotely

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

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

[...]

// Create new EquilateralTriangle MBeans through MLET tags
// The url_2 string is read from the command line
Object mletParams_2[] = {url_2};
String mletSignature_2[] = {"java.lang.String"};
Set mbeanSet = (Set) connectorClient.invoke(
    mletName, "getMBeansFromURL", mletParams_2, mletSignature_2);

for (Iterator i = mbeanSet.iterator(); i.hasNext(); ) {
    Object element = i.next();
    if (element instanceof ObjectInstance) {
        // Success
        echo("OBJECT NAME = " + 
			((ObjectInstance)element).getObjectName());
    } else {
        // Failure
        echo("EXCEPTION = " + ((Throwable)element).getMessage());
    }
}

Now that the class loader has used the code-base of the JAR file, we can create more of the MBeans from the same JAR file. We invoke the createMBean method of the server with the object name of the class loader.


Example 14–8 Reloading MBeans from an Existing Code-Base

// Create another EquilateralTriangle MBean from the same jar file
// used in the MLET 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, mletName,
                            triangleParams, triangleSignature);

Finally, if we have a different code-base not associated with an m-let file, we can give its URL directly to the loader. This enables us to ask the agent to create almost any MBean, imitating a class “push” mechanism.


Example 14–9 Implementing a “Push” Operation

// Add a new URL to the MLet MBean to look for classes
// The url_1 string is read from the command line
Object mletParams_1[] = {url_1};
String mletSignature_1[] = {"java.lang.String"};
connectorClient.invoke(mletName, "addURL",
                       mletParams_1, mletSignature_1);

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

In this way, the manager can make code available on the network, and it can direct its agents to load the classes to create new MBeans ready for management. This mechanism can be used to distribute new resources, provide new services, or update applications, all under the control of the manager.

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. To run it on a different host, modify the code for the Client class constructor where the agent address is specified (see Example 14–6). You can place the JAR files and the m-let file on a remote host and specify its new URL as the parameter to the manager application. We run the example with this file in the current directory.

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


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

In the output of the manager, you can see it create the m-let service MBean, and then load all of the MBeans from different sources. Connect to the agent in a web browser at the following URL:

http://localhost:8082/

Reload its agent view every time the manager pauses, to see the MBeans as they are created.

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


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