JavaEnterprise JavaIntegrating your Java Application with Existing Network Management Solutions with JMX

Integrating your Java Application with Existing Network Management Solutions with JMX

Developer.com content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

What is JMX? If you think that it is one more collateral framework, not deserving your attention, you are deeply mistaken. Java Management eXtensions (JMX) is actually one of the most basic functional parts of modern process of applications development and management. Today, this technology is used by such manufacturers of J2EE-servers, as JBoss, WebLogic, and many others. Below, we shall consider the structure of JMX and examples of use of this technology. After perusal of this material, you will be able to implement JMX functionality in own applications without problems.

The technology JMX (Java Management eXtensions) is a rather new Sun Microsystemss standard that allows Java developers to integrate their applications with existing solutions of network management. JMX defines the standard for a creating of JMX-objects, so-called MBeans. MBeans “live” inside the container. Thus, any JMX client (a remote or local application can act as such a client, for example) has an ability to call methods and to get access to MBeans attributes with the help container in which they are located. The application also can receive special notices (messages) from MBeans if this application registers corresponding MBeans.

Configuration management of any application server of appendices can appear a transitory problem, and the majority of projects simply do not include in a cycle of development configuration framework. In this case, JMX comes to the rescue: You will get a multiuse framework to integrate different functions of remote and local management tools into your applications. JMX allows you to request configuration settings and to change them during the application’s execution. Besides that, JMX also gives other services, such as monitoring, notices on events, the timer, and dynamic loading of classes from XML files. You can use JMX for loading, initialization, changing, and monitoring of your applications and their distributed components.

The detailed specification of JMX technology is in document JSR-000003 (http://www.jcp.org). After consideration of JMX’s architecture, we shall consider examples of how to use JMX together with JSP (Java Server Pages) with the help of the JBoss application server with a JSP/Servlet container, namely Tomcat.

JMX Architecture

The architecture of JMX technology is based on a three-level model. The three logic layers are: instrumentation, agent, and layer of the distributed services (management layer). As a technology, JMX was built with taking into account already existing management technologies; it also gives interfaces to the most widely used reports today: program interfaces for additional management reports give you a means of interaction with other management environments. Clearly, the purpose of these interfaces is closer integration with already existing solutions in the sphere of applications management.

Instrumentation Layer

This layer treats the application as one or several controlled MBean components (Managed Bean). Every MBean gives an opportunity to operate its condition with the help of popular public methods. An MBean can be any Java object that you modify so it supports interfaces and semantics determined in the JMX specification.

There are four types of MBeans: standard, dynamic, open, and model.

  • Standard MBeans provide a static interface.
  • Dynamic MBeans transfer their interface to the JMX agent during application execution with the help of metadata.
  • An Open MBean is the same dynamic MBean, but is uses the predefined types of Java data in a such manner that dependences on other classes are weakened, allowing improved productivity and dynamic behaviour of this component.
  • Model MBean, as follows from the name, is the general and adjustable MBean thatch is delivered with each JMX implementation. You can create a copy and use a model MBean instead of a definition of your own MBean classes.

Standard MBean is the most widespread type. For example, suppose, that you have a class with the name Logger that forms debugging messages of your application, and consists of fields for the log file name (in which these messages will be stored) and a debug level of messages. We can “insert” this Logger class into an MBean with a standard type, creating the new interface with the name LoggerMBean. In this interface, we add public getter and setter methods to install and change values of a file name and debug level. These methods for changing of file name attribute we can call, for example, setFilename() and getFilename(). And, at last, the Logger class needs to implement the LoggerMBean interface so that a JMX agent could analyse and generate independently all the metadata about MBean’s Logger class. This that MBean copes, with the help of a JMX agent, with methods calls determined in the interface (in our case, the LoggerMBean interface). Generally, MBean is a communication between a controlled resource (your application) and the rest of the JMX framework.

Agent Layer

Next, the most interesting JMX framework layer is the agent layer. Agent gives remote access to the management of the application to all registered MBeans. It is possible to tell safely that it is the central part of the JMX framework. The agent layer also provides additional services, such as monitoring and dynamic loading of classes. These services also are registered MBeans. The basic component of the agent is called MBean server and is defined by the javax.management.MBeanServer interface. To create a server, you should call the createMBeanServer() static method of te MBeanServerFactory class. This class factory also stores references to all MBean servers that have been created earlier. Therefore, you are not required to cache them. You can find the reference to the necessary MBean server with the help of a findMBeanServer() method.

Layer of Distributed Services

Last but not least from the considerable number of layers is the layer of management distributed services. This layer provides the interface that is being used by remote tools to interact with agents.

So, we have very briefly considered the structure of the JMX framework, have received some information on what is necessary and what its basic functions are. Next, we will disassemble the practical use of this technology with a concrete example.

Example of a “controled” application

As an example, we shall consider the ordinary GUI Java application: an applet. This applet will contain only one element, JLabel. As a matter of fact, this applet represents a non-functional window with a text label. With the help of JMX, we will have an opportunity to operate the contents of this label. The appearance of our extremely simple applet is shown below:

All code is divided into two parts (two classes): MainApp.java is a class that represents a launching pad of our window and that contains the main() static method; and CounterFrame.java is a class of frame in which, except for elements of a window, a private property counterValue of int type is also defined; it is responsible for storing the current counter value that is displayed in label in our frame. The setCounterValue() and getCounterValue() methods serve for setting and getting the counter’s value, and the incCounterValue() and decCounterValue() methods are intended for increasing and decreasing of counter’s value by 1. All these methods, except for getCounterValue(), automatically update the contents of our label with the counter.

You can examine source code:

// MainApp.java
import java.awt.*;
import javax.swing.UIManager;

public class MainApp {
   private boolean packFrame = false;

   public MainApp() {
      CounterFrame frame = new CounterFrame();
      if (packFrame) 
         frame.pack();
      else 
         frame.validate();

      Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
      Dimension frameSize = frame.getSize();
      if (frameSize.height > screenSize.height) 
         frameSize.height = screenSize.height;
      if (frameSize.width > screenSize.width)
         frameSize.width = screenSize.width;
      frame.setLocation((screenSize.width - frameSize.width) / 2, 
                        (screenSize.height - frameSize.height) / 2);
      frame.setVisible(true);
  }

  public static void main(String[] args) {
     try {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
     } catch (Exception e) {
        e.printStackTrace();
     }
     new MainApp();
  }
}

// CounterFrame.java
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class CounterFrame extends JFrame implements CounterFrameMBean {
   private JPanel contentPane;
   private JLabel jLabel1 = new JLabel();
   private int counterValue = 0; 

   public CounterFrame() {
      enableEvents(AWTEvent.WINDOW_EVENT_MASK);
      try {
         init();
      } catch (Exception e) {
         e.printStackTrace();
      }
   }

   private void init() throws Exception {
      contentPane = (JPanel) this.getContentPane();
      contentPane.setLayout(new BorderLayout());
      this.setSize(new Dimension(400, 300));
      this.setTitle("Example");
      jLabel1.setFont(new java.awt.Font("Dialog", 0, 24));
      jLabel1.setHorizontalAlignment(SwingConstants.CENTER);
      setCounterValue(new Integer(0));
      this.getContentPane().add(jLabel1, BorderLayout.CENTER);
   }

   protected void processWindowEvent(WindowEvent e) {
      super.processWindowEvent(e);
      if (e.getID() == WindowEvent.WINDOW_CLOSING) {
         System.exit(0);
      }
   }

   public Integer getCounterValue() {
      return new Integer(counterValue);
   }

   public void setCounterValue(Integer value) {
      counterValue = value.intValue();
      jLabel1.setText(String.valueOf(getCounterValue().intValue()));
   }

   public void incCounterValue() {
      counterValue++;
      jLabel1.setText(String.valueOf(getCounterValue().intValue()));
   }

   public void decCounterValue() {
      counterValue--;
      jLabel1.setText(String.valueOf(getCounterValue().intValue()));
   }
}

The next step, after creating this applet, according to the parts considered above JMX framework, is to start with the instrumentation layer. Here it is just necessary to allocate methods that carry out a functional part of the application. In our case, it is the getCounterValue(), setCounterValue(), incCounterValue(), and decCounterValue() methods. In other words, for management will be the exposed counterValue field.

Further, we implement an MBean of the standard type, such at which all attributes, operations, and events are determined during compilation by the fixed management interface. So, we will define the interface with the CounterFrameMBean name:

public interface CounterFrameMBean {
   public void setCounterValue(Integer value);
   public Integer getCounterValue();
   public void incCounterValue();
   public void decCounterValue();
}

This interface contains prototypes of methods that are implemented in the CounterFrame class. JMX Agent should independently define which attributes and operations are subject to manipulation and agree with MBean of such a kind. Now, we shall start creating such an JMX Agent.

JMX agent loads MBean into a special MBean server. It also gives a number of necessary services, connectors, and adapters to JMX managers or directly to EMS/NMS.

In the code of agent, it is necessary to put in an executed part of the application, in a main() method of the MainApp class. The code will look like this:

BaseAgent myAgent = new BaseAgent();
myAgent.startAgent( (Object) cms);

The BaseAgent class should carry out at least three functions:

  • Start a MBean server
  • Register a MBean in this MBean server
  • Start a protocol adapter or connector

So, for the first part:

MBeanServer server = MBeanServerFactory.createMBeanServer();

And for the second:

try {
   ObjectName mbName = new ObjectName("MBean:name=CounterFrame");
   server.registerMBean(mbObject, mbName); 
   // mbObject - object, passed to method startAgent() of class CounterFrame
} catch (Exception e) {
   System.out.println("Impossible to register CounterFrameMBean!");
   e.printStackTrace();
   return;
}

And, last, but not least, it is necessary to start a protocol adapter and/or connector to give access to our application to managing applications. There are a number of different ways and variants how to do that. Different manufacturers present their own protocol adapters and connectors. We will take advantage of a class com.sun.jdmk.comm.HtmlAdaptorServer (from the implementation of the JMX specification from Sun Microsystems: http://java.sun.com/products/JavaManagement/). By default, this class will listen to port 8082 for HTTP connections.

Here is the code:

HtmlAdaptorServer hadaptor = new HtmlAdaptorServer();
ObjectName adaptorName = null;
try {
    adaptorName = new ObjectName("Adaptor:name=hadaptor,port=8082");
    server.registerMBean(hadaptor, adaptorName);
} catch(Exception e) {
    System.out.println("?????????? ??????? HTML adaptor!");
    e.printStackTrace();
    return;
}
hadaptor.start();

It’s the final part of our simple JMX agent.

Having compiled all these classes, we will get the complete applicaton that can be operated with a help of a Web browser. It is enough just to go to the http://localhost:8082 address. But, it also is necessary to take into account that, except for the HtmlAdaptorServer class, there is a set of other different control facilities; some of them are built in and others are provided as separate applications.

Additional Abilities of JMX

JMX allows you to carry out many more functions than just a framework of remote management. It gives additional services that you can make the basic part of your development process. We shall see the small list of these opportunities below:

  • Notices on events: Interfaces are supplied with an opportunity of broadcasting notices among events listeners. An Event can be, for example, a simple change of an attribute. It allows MBeans to cooperate with others MBeans or a remote manager and to notify each other on changes of a condition/status.
  • Monitoring: Monitor MBeans can send notices on events to registered listeners. Listener can be another MBean or application. Target objects of supervision over attributes can be counter, gauge, and string. You can read more in detail about them in the specification.
  • The timer: A Timer MBean will send notices to registered listeners on the approach of a certain time or the expiration of the set interval.

Afterword

JMX is a significant and extremely useful framework that you now can integrate with minimal efforts into your application. JMX can easily be integrated with already existing management technologies, for example, SNMP, and also “future” technologies such as CIM/WBEM.

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Latest Posts

Related Stories