Java Dynamic Management Kit 5.1 Tutorial

21.1 Legacy Connector Servers

Java DMK 5.0 introduced the concept of multihome interfaces. This enables you to work in an environment in which multiple network protocols can be used at different times by the legacy connector servers.

The Java DMK legacy connector servers on the server side do not need to have specified local interfaces. By default, the connector server listens on all local interfaces.

There is a legacy connector server for each of the protocols supported in the previous versions of Java DMK: RMI, hypertext transfer protocol (HTTP) and secure HTTP (HTTPS). Support for these protocols is retained in Java DMK 5.1 for reasons of backwards compatibility. All the legacy connectors inherit from the CommunicatorServer class that is the superclass for all the legacy protocol adaptors and connector servers. This class defines the methods needed to control the port and communication settings that are common to all. Each connector server class then provides specific controls, such as the service name for RMI and authentication information for HTTP. This example covers the legacy RMI connector server, and the HTTP authentication mechanism is described in Chapter 23, Legacy Connector Security.

A connector server listens for incoming requests from its corresponding connector client, decodes that request and encodes the reply. Several connector clients can establish connections with the same connector server, and the connector server can handle multiple requests simultaneously. There only needs to be one connector server MBean per protocol to which the agent needs to respond. However, several connector servers for the same protocol can coexist in an agent for processing requests on different ports.

21.1.1 Instantiating a Legacy RMI Connector Server

The legacy RMI connector server is an MBean, so we instantiate its class and register it in the MBean server. This operation could also be performed remotely, for example if a management application wants to access an agent through an alternative protocol.

The code extract shown in Example 21–1 is taken from the BaseAgent class in the examplesDir/current/BaseAgent directory.


Example 21–1 Instantiating the Legacy RMI Connector Server

// Instantiate an RMI connector server with default port
//
CommunicatorServer rmiConnector = new RmiConnectorServer();

try {
    // We let the RMI connector server provide its default name
    ObjectName rmiConnectorName = null;
    ObjectInstance rmiConnectorInstance =
        myMBeanServer.registerMBean( rmiConnector, rmiConnectorName );

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

Other constructors for the legacy RmiConnectorServer class have parameters for specifying the port and the RMI service name that the connector server will use. The default constructor assigns port 1099 and name=RmiConnectorServer, as given by the static variables RMI_CONNECTOR_PORT and RMI_CONNECTOR_SERVER, respectively, of the ServiceName class. Both attributes can also be accessed through the getter and setter methods of the legacy RmiConnectorServer class.

Each legacy connector uses different parameters that are specific to its protocol. For example, the HTTP connector does not need a service name. The default values for all parameters are given by the static variables of the ServiceName class.

Registering a connector server as an MBean implies that its MBean server will handle the remote requests that it receives. However, you can specify a different object for fulfilling management requests through the setMBeanServer method that the RmiConnectorServer class inherits from the CommunicatorServer class. For security reasons, this method is not exposed in the legacy RMI connector server MBean, so it must be called from the agent application.

Registering the connector server as an MBean is optional. For example, you might not want it exposed for management. In this case, you must use the setMBeanServer method to specify an object that implements the MBeanServer interface so that it can fulfill management requests.

A user can select a local server interface for a legacy RMI connector server using the RMI property java.rmi.server.hostname.

21.1.2 Connector States

Like all communicator servers, the legacy RMI connector server has a connection state that is identified by the static variables of the CommunicatorServer class:

All connector servers are OFFLINE after their instantiation, so they must be started explicitly. Then, you must wait for a connector server to come ONLINE before it can respond to connections on its designated port.


Example 21–2 Starting the RMI Connector Server

// Explicitly start the RMI connector server
//
rmiConnector.start();

// waiting for it to leave starting state...
while (rmiConnector.getState() == CommunicatorServer.STARTING) {
    try {
        Thread.sleep( 1000 );
    } catch (InterruptedException e) {
        continue;
    }
}

Instead of blocking the application thread, you can register a listener for attribute change notifications concerning the State attribute of the connector server MBean. All connector servers implement this notification which contains both old and new values of the attribute (see 8.3 Attribute Change Notifications). Listeners in the agent can then asynchronously detect when the state changes from STARTING to ONLINE.


Note –

During the STARTING state, the legacy RMI connector server registers its RMI service name with the RMI registry on the local host for its designated port. If no registry exists, one is instantiated for the given port. Due to a limitation of version 1.4 of the Java platform, creating a second registry in the same Java virtual machine (JVM) will fail. As a workaround, before starting an RMI connector server on a new, distinct port number in an agent, you must run the rmiregistry command from a terminal on the same host. This limitation is specific to the legacy RMI connector. The HTTP protocols do not require a registry.


The stop method is used to take a connector server offline. The stop method is also called by the preDeregister method that all connector servers inherit. Stopping a connector server interrupts all requests that are pending and closes all connections that are active. When a connection is closed, all of its resources are cleaned up, including all notification listeners, and the connector client can be notified by a heartbeat notification (see 21.3 Legacy Heartbeat Mechanism). A connection that is closed can no longer be reopened. The connector client must establish a new connection when the connector server is restarted.

The setPort method that all connector servers inherit from the CommunicatorServer class enables you to change the port on which management requests are expected. You can only change the port when the connector server is offline, so it must be explicitly stopped and then restarted. The same rule applies to the setServiceName method that is specific to the RMI connector server. These methods are also exposed in the MBean interface, along with start and stop, enabling a remote management application to configure the connector server through a different connection.