Skip to main content

An Introduction to JMXRemote

December 20, 2005

{cs.r.title}









Contents
Using the javax.management Packages
Introducing JMXRemote
Features of JMXRemote
   Support Standard MBean, Dynamic MBean, and
Model MBean Register
   Support MBean Attributes and Operations Access
   Support MBeanRegistration Interface
   Support NotificationBroadcaster Interface
   Support MBean Health Check
What's Inside Remote MBean Server
   MBean Register
   MBean Attributes and Operations Access
   MBean Notification Broadcast
   MBean Health Check
Integration with Spring
Conclusion
Reference

The Java Management Extensions (JMX) API has been added into J2SE 1.5 as a standard Java API. The package javax.management.remote makes it possible to remotely access a JMX MBean server.

On the server side, JMXConnectorServer is a connector server MBean registered in the MBeanServer. It listens for client connection requests and creates a connection for each one. On the client side, JMXConnector is used to establish a connection to a connector server. An MBeanServerConnection--a super-interface of MBeanServer--can be retrieved from the JMXConnector, representing a remote MBean server. The client can use this class to do most MBean server operations, such as MBean creation and attribute access, and MBean operation invocation. Actually, javax.management.MBeanServerConnection is a super-interface of javax.management.MBeanServer.

But in some circumstances, that is not enough. In a JMX-enabled project, it is a common requirement to register a local MBean to the remote MBean server. This registration function--registerMBean()--is only defined in MBeanServer, but not supported in javax.management.MBeanServerConnection.

JMXRemote is a project to satisfy this requirement. It provides a remote MBean server delegation to the local application as if it were a local MBean server.

This article introduces the features of JMXRemote project with samples and implementation details. Furthermore, it has a section to introduce how to integrate JMXRemote with the Spring framework.

Using the javax.management Packages

The following code example demonstrates how to use the javax.management.remote package to access an MBean server remotely. Server is a server hosting an MBean server, while Client is a client application to access the remote MBean server. In this example, rmiregistry is used as a JNDI server. Remember to run rmiregistry first.

package org.jingle.test.jmxremote.article;

import java.util.HashMap;

import javax.management.*;
import javax.management.remote.*;
import javax.management.remote.rmi.*;
import com.sun.jdmk.comm.*;
import com.sun.jndi.rmi.registry.*;

public class Server {
  protected MBeanServer server = null;
  String serviceURL = "service:jmx:rmi:" +
  "//localhost/jndi/rmi://localhost:1099/test";
  public void run() {
    try {
    // create MBean server
      server = MBeanServerFactory.
                 createMBeanServer("test");
      // create JMXConnectorServer MBean
      HashMap<String, String> map =
           new HashMap<String, String>();
      map.put("java.naming.factory.initial",
         RegistryContextFactory.class.getName());
      map.put(
        RMIConnectorServer.JNDI_REBIND_ATTRIBUTE,
        "true");
      JMXConnectorServer connector =
        JMXConnectorServerFactory
        .newJMXConnectorServer(
            new JMXServiceURL(serviceURL),
            map, server);
      // register the connector server as an MBean
      server.registerMBean(connector,
              new ObjectName(
                  "system:name=rmiconnector"));
      // start the connector server
      connector.start();
      // create html adapter mbean
      HtmlAdaptorServer adapter =
          new HtmlAdaptorServer();
      ObjectName httpName =
          new ObjectName("system:name=http");
      server.registerMBean(adapter, httpName);
      adapter.setPort(9292);
      adapter.start();
      doOper();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
  protected void doOper() {
    System.out.println(
      "Server is ready to serve");
  }
  public static void main(String[] args) {
    new Server().run();
  }
}
Server creates an MBean server and registers the JMXConnectorServer as a connector MBean. The connector is also exported to the JNDI server as a remote object.

Now here's the client:

package org.jingle.test.jmxremote.article;

import java.io.IOException;
import java.util.HashMap;
import javax.management.*;
import javax.management.remote.*;

import com.sun.jndi.rmi.registry.*;

public class Client {
  String serviceURL =
    "service:jmx:rmi:" +
    "//localhost/jndi/rmi://localhost:1099/test";

  protected MBeanServerConnection conn = null;

  public void run() {
    try {
      HashMap<String, String> map =
                  new HashMap<String, String>();
      map.put("java.naming.factory.initial",
          RegistryContextFactory.class.getName());
      JMXConnector connector = JMXConnectorFactory
          .connect(new JMXServiceURL(serviceURL));
      conn = connector.getMBeanServerConnection();
      doOper();
      synchronized (this) {
        this.wait();
      }
      connector.close();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  protected void doOper() {
    try {
      System.out.println("MBean count = " +
          conn.getMBeanCount());
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  public static void main(String[] args) {
    new Client().run();
  }
}
Client creates a JMXConnector to connect to the remote JMXConnectorServer. Through the MBeanServerConnection retrieved from JMXConnector, the client application can access the MBean server remotely. Please refer to the JMX API Javadoc for more detailed information.

Introducing JMXRemote

Although the MBeanServerConnection can be used to do most of the operations defined in MBeanServer, there is one important function missing: registerMBean(). This function is only defined in MBeanServer instead of its super-interface MBeanServerConnection. In a JMX-enabled project, there may be many modules (MBeans) distributed in different JVMs. It is a quite common requirement to register local MBean instances to a central MBean server.

JMXRemote is a simple extension of MBeanServerConnection to support the registerMBean() function.

public class MBeanServerImpl implements
              MBeanServer, NotificationListener {
        public MBeanServerImpl(
               MBeanServerConnection connection);
        ...
}

JMXRemote provides a MBeanServerImpl, which implements the MBeanServer interface and takes a MBeanServerConnection instance as a parameter. Figure 1 shows the class diagram of MBeanServerImpl.

Class diagram of MBeanServerImpl
Figure 1. Class diagram of MBeanServerImpl

MBeanServerImpl delegates most of the operations to the MBeanServerConnection instance. What MBeanServerImpl really does is:

public ObjectInstance registerMBean(Object inst,
                                ObjectName name);

All of the features supported by MBeanServerImpl are based on this function. In order to demonstrate the features more clearly, I'll modify the Server a little to register an HtmlAdaptorServer MBean, which is used to serve HTTP requests. Then, the demonstration output can be viewed in a web browser.

package org.jingle.test.jmxremote.article;

import java.util.HashMap;
import javax.management.*;
import javax.management.remote.*;
import javax.management.remote.rmi.*;
import com.sun.jdmk.comm.HtmlAdaptorServer;

public class Server {
  public static void main(String[] args) {
    try {
      ....
      //create html adapter mbean
      HtmlAdaptorServer adapter =
                         new HtmlAdaptorServer();
      ObjectName httpName =
              new ObjectName("system:name=http");
      server.registerMBean(adapter, httpName);
      adapter.setPort(9292);
      adapter.start();

    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}
HtmlAdaptorServer is defined in the Sun JMX 1.2.1 Reference Implementation. Now, you can access the URL http://127.0.0.1:9292 in your web browser to see the JMX agent view. Figure 2 shows the screen shot.

Screenshot of JMX Agent View (1)
Figure 2. JMX agent view







Features of JMXRemote

JMXRemote's goal is to make it transparent to local applications. It can be treated as if it were a real local MBean server.

Support Standard MBean, Dynamic MBean, and Model MBean Register

A standard MBean is a type of MBean that has well-known, static management interfaces. A dynamic MBean uses metadata classes to describe its management interfaces at runtime in a generic fashion. A model MBean is a special dynamic MBean whose management interface is defined outside of the MBean and inserted into the MBean via a setter method. For detailed information about these types of MBeans, please refer to the reference section for JMX-related books.

MBeanServerImpl can register the above three kinds of MBeans.

Take the standard MBean as an example.

package org.jingle.test.jmxremote.article.standard;
public interface StandardMBean {
    public void setNumber(int number);
    public int getNumber();
    public boolean guessNumber(int number);
}


package org.jingle.test.jmxremote.article.standard;
public class Standard implements StandardMBean {
    int number = 0;
    public void setNumber(int number) {
        this.number = number;
    }
    public int getNumber() {
        return number;
    }
    public boolean guessNumber(int number) {
        return (this.number == number);
    }
}
Standard is a very simple MBean. It has one attribute, Number, and one operation, guessNumber.

package org.jingle.test.jmxremote.article.standard;

import javax.management.*;
import org.jingle.jmxremote.client.MBeanServerImpl;
import org.jingle.test.jmxremote.article.Client;

public class StandardClient extends Client {
  protected void doOper() {
    try {
      MBeanServer server =
                       new MBeanServerImpl(conn);
      Standard mbean = new Standard();
      server.registerMBean(mbean, new ObjectName(
                  "sample:name=standard mbean"));
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  public static void main(String[] args) {
    new StandardClient().run();
  }
}
StandardClient registers the Standard MBean instance to the remote MBean server just like a local one. Figures 3 and 4 show the screenshots of the JMX agent view and MBean view, respectively.

The Screenshot of JMX Html View (2)
Figure 3. JMX agent view

The Screenshot of JMX MBean View
Figure 4. JMX MBean view

Support MBean Attributes and Operations Access

The attributes and operations of the MBeans registered in the MBeanServerImpl can be accessed as normal. To demonstrate this feature, you can set the Number attribute and invoke the guessNumber operation from the JMX MBean view.

Support MBeanRegistration Interface

If the MBean implements MBeanRegistration interface, the callback methods defined in the interface will be invoked during the registration and deregistration procedures.

package org.jingle.test.jmxremote.article.standard;

import javax.management.*;

public class StandardWithMBeanRegistration
    extends Standard implements MBeanRegistration {
  public ObjectName preRegister(MBeanServer server,
                ObjectName name) throws Exception {
    return new ObjectName("sample:name=" +
         "standard mbean with mbean registration");
    }
    public void postRegister(
                        Boolean registrationDone) {
    }
    public void preDeregister() throws Exception {
    }
    public void postDeregister() {
        System.out.println("Deregistered");
    }
}
StandardWithMBeanRegistration implements the MBeanRegistration interface to change the MBean name before registration.

package org.jingle.test.jmxremote.article.standard;

import javax.management.*;
import org.jingle.jmxremote.client.MBeanServerImpl;
import org.jingle.test.jmxremote.article.Client;

public class StandardWithMBeanRegistrationClient
                                   extends Client {
  protected void doOper() {
    try {
        MBeanServer server =
                         new MBeanServerImpl(conn);
        Standard mbean =
               new StandardWithMBeanRegistration();
        server.registerMBean(MBean, new ObjectName(
                "sample:name=standard MBean"));
    } catch (Exception e) {
        e.printStackTrace();
    }
  }
  public static void main(String[] args) {
    new StandardWithMBeanRegistrationClient().run();
  }
}

Run StandardWithMBeanRegistrationClient, and you will find that the MBean name is standard mbean with mbean registration.

Support NotificationBroadcaster Interface

If the MBean implements NotificationBroadcaster, it can manage a list of notification listeners and dispatch the notification to all listeners when there is any notification to be emitted. On the flip side, a NotificationListener can register with any NotificationBroadcaster and receive notifications.

package org.jingle.test.jmxremote.article.standard;

import java.util.Date;
import javax.management.*;

public class StandardWithNotificationBroadcaster
               extends Standard
               implements NotificationBroadcaster {
  NotificationBroadcasterSupport notifSupport =
              new NotificationBroadcasterSupport();

  public void setNumber(int number) {
    int oldNumber = getNumber();
    super.setNumber(number);
    int newNumber = getNumber();
    if (oldNumber != newNumber) {
        notifSupport.sendNotification(
                   new AttributeChangeNotification(
        "StandardWithNotificationBroadcaster",
        1, new Date().getTime(),
        "number changed", "Number",
        Integer.TYPE.getName(),
        new Integer(oldNumber),
        new Integer(newNumber)));
    }
  }
  public void addNotificationListener(
                     NotificationListener listener,
                     NotificationFilter filter,
                     Object handback) {
    notifSupport.addNotificationListener(listener,
                                 filter, handback);
  }
  public MBeanNotificationInfo[]
                            getNotificationInfo() {
        return notifSupport.getNotificationInfo();
  }
  public void removeNotificationListener(
                 NotificationListener listener)
                 throws ListenerNotFoundException {
    notifSupport.removeNotificationListener(
                                         listener);
  }
}
StandardWithNotificationBroadcaster implements NotificationBroadcaster and delegates all related operations to the internal NotificationBroadcasterSupport. The setNumber() method is overridden to emit an AttributeChangeNotification when the Number attribute is set to a different value.

package org.jingle.test.jmxremote.article.standard;

import javax.management.*;
import org.jingle.jmxremote.client.MBeanServerImpl;
import org.jingle.test.jmxremote.article.Client;

public class
    StandardWithNotificationBroadcasterClient
    extends Client {
  protected void doOper() {
    try {
      MBeanServer server =
                     new MBeanServerImpl(conn);
      Standard mbean =
         new StandardWithNotificationBroadcaster();
      server.registerMBean(mbean, new ObjectName(
                "sample:name=standard mbean"));
    } catch (Exception e) {
        e.printStackTrace();
    }
  }
  public static void main(String[] args) {
    new
      StandardWithNotificationBroadcasterClient().
      run();
  }
}

The StandardWithNotificationBroadcasterClient is used to register the StandardWithNotificationBroadcaster MBean to the remote MBean server.

package org.jingle.test.jmxremote.article.standard;

import javax.management.*;
import org.jingle.test.jmxremote.article.Client;

public class StandardNotificationListenerClient
   extends Client implements NotificationListener {
  protected void doOper() {
    try {
      ObjectName standardName = new ObjectName(
                "sample:name=standard mbean");
      conn.addNotificationListener(standardName,
                this, null, "client");
    } catch (Exception e) {
        e.printStackTrace();
    }
  }
  public void handleNotification(
     Notification notification, Object handback) {
    String type = notification.getType();
    if (type.equals(AttributeChangeNotification.
                              ATTRIBUTE_CHANGE)) {
      System.out.println(
                "notification = " + notification);
      System.out.println("oldValue = " +
       ((AttributeChangeNotification) notification)
                                   .getOldValue());
      System.out.println("newValue = " +
       ((AttributeChangeNotification) notification)
                                   .getNewValue());
      System.out.println("handback = " + handback);
    }
  }
  public static void main(String[] args) {
    new StandardNotificationListenerClient().run();
  }
}
StandardNotificationListenerClient implements NotificationListener. It registers itself to the standard MBean to receive notifications, and expects the notifications to contain a handback object: client. Once the standard MBean emits an AttributeChangeNotification, it will print out the notification details.

Now, try to change the Number attribute from the JMX MBean view. The output of NotificationListenerClient is as follows:

notification =
javax.management.AttributeChangeNotification
[source=StandardWithNotificationBroadcaster]
[type=jmx.attribute.change]
[message=number changed]
oldValue = 0
newValue = 10
handback = client
Support MBean Health Check

Because the remote MBean server and real MBean server are in different JVMs, a health check is important. The health check is bidirectional. If either one finds that the other is disconnected, it will de-register all related MBeans registered on it.

Run StandardWithMBeanRegistrationClient and make sure you can find the MBean named name=standard mbean with mbean registration in the JMX agent view. Stop StandardWithMBeanRegistrationClient and refresh the JMX agent view after a few seconds. You will find that the MBean has disappeared.

Run StandardWithMBeanRegistrationClient again. Stop Server, and you will find that the MBean's postDeregister callback function is called after a few seconds.

All above samples only cover standard MBeans. For dynamic mbeans and model mbeans, please refer to the JMXRemote samples.







What's Inside Remote MBean Server

JMXRemote has two parts: a client part and a server part. Until now, we've focused on the client part. To discover the magic inside, we will go into the server side in this section.

The core server-side component is RemoteAdapter, which implements the features above to serve all of the JMXRemote clients.

MBean Register

On the client side, when registerMBean is requested, MBeanServerImpl introspects the target MBean, collects necessary information (for example, whether it implements the MBeanRegistration or NotificationBroadcaster interface), and generates the MBeanInfo according to the target MBean type. It then checks whether there is a RemoteAdapter MBean registered in the MBean server. If not, it asks the MBean server to create one. It also registers itself as a NotificationListener to receive notifications from the RemoteAdapter. After that, it invokes the createDynamicMBean operation in the RemoteAdapter to create and register an MBean in the MBean server. If the target MBean implements the NotificationBroadcaster interface, MBeanServerImpl also adds a RemoteNotificationListener to it.

On the server side, RemoteAdapter receives the createDynamicMBean request from the client and creates an MBean (DynamicMBean or ModelMBean) according to the MBeanInfo from the client. Then it generates a suitable wrapper for the MBean at the runtime to make sure that the wrapper has the same interfaces/functions as the target MBean has. Finally, RemoteAdapter registers the wrapper as an MBean in the MBeanServer.

Figure 5 shows the sequence diagram of the MBean register.

The sequence diagram of mBean register
Figure 5. The sequence diagram of the MBean register

MBean Attributes and Operations Access

On the server side, the MBean server dispatches the caller's request to the getAttribute(), setAttribute(), or invoke() method of the requested DynamicMBean or ModelMBean. These methods call RemoteAdapter to send out a proper notification according to the different requests. Of course, the NotificationFilter takes effect to make sure that the notification is sent only to the correct client (remember that MBeanServerImpl registers itself as a NotificationListener to the RemoteAdapter). The notification contains a sequence ID and MBean's object name as its identity. In the meantime, the thread waits there for the response. The thread is resumed when the response from the client returns. Finally, the response is returned to the MBean server to finish the request invocation. This procedure uses an asynchronous notification mechanism to simulate the synchronized invocation.

On the client side, MBeanServerImpl receives the notification from RemoteAdapter. It translates the notification to a proper method call on a proper MBean, according to the object name in the notification. Then MBeanServerImpl invokes the returnResult() operation in RemoteAdapter with operation result and notification sequence ID.

Figure 6 is the sequence diagram of the MBean operation invocation.

The sequence diagram of MBean operation invocation
Figure 6. The sequence diagram of MBean operation invocation

MBean Notification Broadcast

On the client side, the MBean sends out notifications to all notification listeners, including the RemoteNotificationListener. The RemoteNotificationListener then invokes the fireNotification() operation in RemoteAdapter with the notification and MBean's object name to broadcast the notification.

On the server side, RemoteAdapter receives the notification and finds a proper MBean according to the object name. Then it invokes the MBean's sendNotification() to broadcast the notification to all registered listeners.

Figure 7 shows the sequence diagram of the MBean notification broadcast.

The sequence diagram of MBean notification broadcast
Figure 7. The sequence diagram of MBean notification broadcast

MBean Health Check

On the client side, MBeanServerImpl defines a timer to do a specific job periodically. The job adds a time unit to the lifetime of each MBean that is registered in this remote MBean server. Then it invokes the ping() operation in RemoteAdapter with all MBeans' object names. The operation's response contains all of the responsive MBeans' object names. For each responsive MBean, its "lifetime" is refreshed. Finally, the job de-registers those MBeans with an expired lifetime.

On the server side, RemoteAdapter receives a list of the MBeans' object names. It refreshes the lifetime of corresponding MBeans and filters out invalid object names from the list. The list is returned to the client as the operation response. RemoteAdapter also defines a timer to periodically add a time unit to the lifetime of each registered MBean. If the MBean's lifetime is expired, RemoteAdapter deregisters it from the MBean server.

Integration with Spring

Spring is a popular framework for Java applications. JMXRemote can be integrated into the Spring framework easily, as seen below.

package org.jingle.test.jmxremote.article.spring;

import org.springframework.context.*;
import org.springframework.context.support.*;

public class SpringServer {
  public static void main(String[] args) {
    ApplicationContext context =
            new ClassPathXmlApplicationContext(
                                           "server.xml");
  }
}
SpringServer has the same function as the previously seen Server. Most of the code in Server has been moved into the XML config file.

<!--sever.xml-->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
  <bean id="mbeanServer"
    class="org.springframework.jmx.support.MBeanServerFactoryBean"/>
  <bean id="serverConnector"
    class="org.springframework.jmx.support.ConnectorServerFactoryBean">
    <property name="objectName" value="system:name=rmiconnector"/>
    <property name="serviceUrl"
     
value="service:jmx:rmi://localhost/jndi/rmi://localhost:1099/test"/>
    <property name="environment">
      <props>
        <prop key="jmx.remote.jndi.rebind">true</prop>
      </props>
    </property>
  </bean>
  <bean id="exporter"
class="org.springframework.jmx.export.MBeanExporter">
    <property name="autodetect" value="true"/>
    <property name="beans">
      <map>
        <entry key="system:name=http" value-ref="htmlAdapter"/>
      </map>
    </property>
  </bean>
  <bean id="htmlAdapter"
    class="com.sun.jdmk.comm.HtmlAdaptorServer" init-method="start">
    <property name="port" value="9292"/>
  </bean>
</beans>
mbeanServer is a FactoryBean that is used to create MBeanServer. An exporter registers the htmlAdapter MBean to the MBeanServer.

package org.jingle.test.jmxremote.article.spring;

import org.springframework.context.*;
import org.springframework.context.support.*;

public class SpringClient {
  public static void main(String[] args) {
    try {
      ApplicationContext context =
                  new ClassPathXmlApplicationContext(
                                   "client.xml");
      synchronized (Thread.currentThread()) {
        Thread.currentThread().wait();
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

Like SpringServer, SpringClient just initializes the application context. All other code is moved into the XML config file.

<!--client.xml-->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
  <bean id="clientConnector"
   
class="org.springframework.jmx.support.MBeanServerConnectionFactoryBean">
    <property name="serviceUrl"
     
value="service:jmx:rmi://localhost/jndi/rmi://localhost:1099/test"/>
  </bean>
  <bean id="mbeanServer"
    class="org.jingle.jmxremote.client.spring.MBeanServerFactoryBean">
    <property name="connection">
      <ref bean="clientConnector"/>
    </property>
  </bean>

  <bean id="exporter"
    class="org.springframework.jmx.export.MBeanExporter">
    <property name="autodetect" value="true"/>
    <property name="server">
      <ref bean="mbeanServer"/>
    </property>

    <property name="beans">
      <map>
        <entry key="sample:name=standard mbean" value-ref="standard"/>
      </map>
    </property>
  </bean>
  <bean id="standard"
    class="org.jingle.test.jmxremote.article.standard.Standard"/>
</beans>
MBeanServerFactoryBean is a JMXRemote plugin for the Spring framework. It acts as a FactoryBean to generate an MBeanServer instance. MBeanExporter uses this remote MBean server to register MBeans as if it were using a local MBean server. An obvious advantage is that whether the MBean server is local or remote, it is transparent to the application code, which makes the code more portable. The application can run with a local MBean server without any code change.

One useful feature of Spring JMX support is that Spring can expose the properties and methods of simple Java beans as attributes and operations of a JMX MBean. In fact, MBeanExporter in Spring introspects the simple bean and generates a ModelMBean according to the simple bean's attributes and operations. Since JMXRemote can support ModelMBean, this feature is also supported neatly by the JMXRemote plugin.

package org.jingle.test.jmxremote.article.spring;

public class SimpleBean {
    int number = 0;
    public void setNumber(int number) {
        this.number = number;
    }
    public int getNumber() {
        return number;
    }
    public boolean guessNumber(int number) {
        return (this.number == number);
    }
}
SimpleBean is a simple Java bean without any JMX support.

<!--client.xml-->
...
<beans>
  ...
  <bean id="exporter"
    class="org.springframework.jmx.export.MBeanExporter">
    ...
    <property name="beans">
      <map>
        <entry key="sample:name=standard mbean" value-ref="standard"/>
        <entry key="sample:name=simple mbean"
value-ref="simple"/>

      </map>
    </property>
  </bean>
  ...
  <bean id="simple"
    class="org.jingle.test.jmxremote.article.spring.SimpleBean"/>

</beans>

Add SimpleBean to the MBeanExporter's bean list in client.xml, and you can check the result in the JMX agent view.

Conclusion

J2SE 1.5 introduces JMX as part of the standard Java API. The remote package of the JMX API can help you access the MBean server remotely. But that is not enough. JMXRemote makes use of MBeanServerConnection to construct a delegation for the MBean server for remote use. A local application can use this delegation to do most of the MBean server operations as if it were using a local MBean server. JMXRemote also provides a plugin to integrate with Spring, which makes the JMX-enabled application simpler and more portable.

Reference

width="1" height="1" border="0" alt=" " />
Lu Jian is a senior Java architect/developer with four years of Java development experience.
Related Topics >> Programming   |