Java Dynamic Management Kit 5.1 Tutorial

21.2.4 Managing MBeans Remotely

Once the connection to an agent is established, the management application can access that agent's MBeans through the legacy RemoteMBeanServer interface of the connector client. Invoking these methods has exactly the same effect as calling the equivalent methods directly on the MBean server instance.

It is possible to restrict access to certain methods of the MBean server when they are called through the legacy connector client, but this is performed by a security mechanism in the legacy connector server. See 23.2 Context Checking for more details.

21.2.4.1 Creating and Unregistering MBeans in the Agent

We use the createMBean method to instantiate and register an object from its class name. This class must already be available in the agent application's classpath.


Example 21–4 Creating and Unregistering an MBean Remotely

private void doWithoutProxyExample(String mbeanName) {

    try {

        // build the MBean ObjectName instance
        //
        ObjectName mbeanObjectName = null;
        String domain = connectorClient.getDefaultDomain();
        mbeanObjectName = new ObjectName( domain + ":type=" + mbeanName );

        // create and register an MBean in the MBeanServer of the agent
        //
        echo("\nCurrent MBean count in the agent = "+
             connectorClient.getMBeanCount());
        echo("\n>>> CREATE the " + mbeanName +
             " MBean in the MBeanServer of the agent:");
        String mbeanClassName = mbeanName;

        ObjectInstance mbeanObjectInstance =
        connectorClient.createMBean( mbeanClassName, mbeanObjectName );

        echo("\tMBEAN CLASS NAME      = " +
             mbeanObjectInstance.getClassName() );
        echo("\tMBEAN OBJECT NAME     = " +
             mbeanObjectInstance.getObjectName() );
        echo("\nCurrent MBean count in the agent = "+
             connectorClient.getMBeanCount() );

        [...] // Retrieve MBeanInfo and access the MBean (see below)

        // unregister the MBean from the agent 
        //
        echo("\n>>> UNREGISTERING the "+ mbeanName +" MBean");
        connectorClient.unregisterMBean(
            mbeanObjectInstance.getObjectName() );

        [...]

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

Example 21–4 shows the use of other calls to the remote agent, such as getDefaultDomain and getMBeanCount that have the same purpose as in an agent application.

21.2.4.2 Accessing MBean Attributes and Operations

Once you can access the object names for MBeans in the agent, you can know their management interface from their MBeanInfo object. The code in Example 21–5 is actually called in between the MBean creation and unregistration shown in Example 21–4.


Example 21–5 Retrieving the MBeanInfo Object

ObjectName mbeanObjectName = mbeanObjectInstance.getObjectName();

echo("\n>>> Getting the management information of the MBean");
MBeanInfo info = null;
try {

    info = connectorClient.getMBeanInfo( mbeanObjectName );

} catch (Exception e) {
    echo("\t!!! Could not get MBeanInfo object for "+ mbeanObjectName );
    e.printStackTrace();
    return;
}

// display content of MBeanInfo object
//
echo("\nCLASSNAME: \t"+ info.getClassName());
echo("\nDESCRIPTION: \t"+ info.getDescription());
echo("\nATTRIBUTES");
MBeanAttributeInfo[] attrInfo = info.getAttributes();
if ( attrInfo.length>0 ) {
    for( int i=0; i<attrInfo.length; i++ ) {
        echo(" ** NAME: \t"+ attrInfo[i].getName());
        echo("    DESCR: \t"+ attrInfo[i].getDescription());
        echo("    TYPE: \t"+ attrInfo[i].getType() +
             "\tREAD: "+ attrInfo[i].isReadable() +
             "\tWRITE: "+ attrInfo[i].isWritable());
    }
} else echo(" ** No attributes **");

[...]

It is then straightforward to perform management operations on MBeans through the legacy connector client. As in an agent, we call the generic getters, setters, and call methods with the object name of the MBean, the name of the attribute or operation, and any parameters. As in the methods of the MBean server, we need to use the Attribute and AttributeList classes to pass attributes as name-value pairs.


Example 21–6 Accessing an MBean Through the Legacy Connector Client

try {
    // Getting attribute values
    String State = (String)
        connectorClient.getAttribute( mbeanObjectName, "State" );
    Integer NbChanges = (Integer)
        connectorClient.getAttribute( mbeanObjectName, "NbChanges" );
    echo("\tState     = \"" + State + "\"");
    echo("\tNbChanges = " + NbChanges);

    // Setting the "State" attribute
    Attribute stateAttr = new Attribute("State", "new state from client");
    connectorClient.setAttribute(mbeanObjectName, stateAttr);

    // Invoking the "reset" operation
    Object[] params = new Object[0];
    String[] signature = new String[0];
    connectorClient.invoke(mbeanObjectName, "reset", params, signature);

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

All other MBean access methods are available in the same manner, such as bulk getters and setters, and the query methods.

21.2.4.3 Creating and Accessing Dynamic MBeans

In the first run of the example, the management application creates, manages, and unregisters a standard MBean in the remote agent. However, standard and dynamic MBeans are designed to be managed through the same methods, both in the MBeanServer and in the RemoteMBeanServer interfaces.

As shown in Example 21–4, the subroutine of the example application takes only a single class name parameter. The first time this subroutine is called, the example passes the class name of a standard MBean, and the second time, that of a dynamic MBean. For the example to run, the two MBeans must have an identical management interface. By extension of this special case, we see that the connector client can manage dynamic MBeans through the same methods as it manages standard MBeans, without making any distinction between the two.