The latest release of Java, J2SE 5.0 (codenamed Tiger), adds core support for the Java Management Extensions (JMX) 1.2 into the Java standard libraries. This article walks you through how to use the JMX support in J2SE 5.0, including the new JConsole application, to monitor and manage your own applications both locally and remotely.
The Java Management Extensions provide a set of tools and APIs for applying a standard client/server-based architecture to monitoring and management of a Java application. A JMX Agent is deployed into the application that is to be managed and monitored. A JMX Client then connects to the agent to perform management and/or monitoring activities, as shown in Figure 1 below.
The technologies that make up JMX, in different incarnations, have been available for some time in an optional download. In Java 1.5 (J2SE 5.0), JMX has been packaged into the standard libraries that come with the new version of Java. For the first time, the tools to monitor your application's performance are first-class citizens in any Java developer's toolbox.
In addition to incorporating JMX into the core support in the J2SE 5.0, a new application has been added in order to provide an example JMX Client application. That application is called JConsole and it is available in the %JAVA_HOME%/bin directory of your J2SE 5.0 installation. JConsole provides a nicely featured application that exercises many of the JMX 1.2 features such as connecting to, monitoring, and managing local and remote JMX-enabled Java applications.
Figure 1. A simple overview of how a JMX Client can connect to a local or remote JMX Agent that is monitoring an application
Whether you are monitoring a simple Java Desktop application or a full Enterprise suite, JMX provides a standard means by which you can get at the details of your application's performance, and even interact with the application and its host JVM, should you need to.
JMX 1.2 comes bundled as part of J2SE 5.0 and so, if you haven't already, it is worth downloading and installing the latest revision of J2SE 5.0 that is available (rc at the time this article was published). Once you have installed the version of J2SE 5.0 for your specific operating system and set up the corresponding
PATH variable to point to the newly installed version of Java, then you should be able to run the
java command to get the following output:
> java -version java version "1.5.0-rc" Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-rc-b63) Java HotSpot(TM) Client VM (build 1.5.0-rc-b63, mixed mode, sharing)
If you get "1.5.0-rc" when you run the
java command with the
-version option, then you are all set to use J2SE 5.0. Since JMX 1.2 comes as part of the J2SE installation, you do not need to do anything more to start deploying and using applications that are monitored using JMX.
Windows users, take note: JMX will not work correctly if your Windows operating system is booting from a FAT32 partition, even if the permissions are set up correctly. The reasons for this are mentioned in Sun's "Introduction to JMX." As a general rule of thumb, if you want to use JMX for remote (or even local) monitoring on Windows, then make sure your Windows boot disk is formatted as NTFS.
This article comes with a simple Java application that can be used to test out the management and monitoring facilities available in JMX 1.2. The application contains two classes that do nothing more than open a single window that contains a button and, when that button is pressed, create a new window with a loaded image, as shown in Figure 2.
Figure 2. The simple example application that this article monitors using JMX 1.2 and JConsole
The example application is deliberately simple in order to keep the focus on JMX while also exercising the performance of the application's JVM a little, so as to cause some effects that make the application more interesting when it is being monitored.
See the References section to download the example application.
Once you have downloaded the example code you can compile the example application using an IDE such as Eclipse, or from the command line using the
> javac -d %PROJECT_DIRECTORY% \ com/oreilly/onjava/jmxexample/SimpleApplication.java
Editor's note: This command should be typed all as one line. We've added line breaks, indicated by the
\ marks, to fit the ONJava web page layout.
You do not need to add anything special at compile time in order to prepare your applications for JMX. One of the benefits of using JMX is that it is a runtime configuration option, rather than something that has to be considered at compile time. This means that you can enable management and monitoring using JMX on any application, regardless of how it was initially compiled into byte code.
Users of older versions of the J2SDK, take note: While developing the code for this article, the JMX 1.2 Agent in J2SE 5.0 was tested to work with applications compiled under JDK 1.4 and 1.5. It is likely that JDK 1.3 would also work, but this was not tested.
When you have successfully compiled the example application, you can run it using the normal
java command, specifying the additional
com.sun.management.jmxremote Java system property to enable the JMX Agent:
java -Dcom.sun.management.jmxremote \ -classpath %PROJECT_DIRECTORY% \ com.oreilly.onjava.jmxexample.SimpleApplication
The example application should start running with no errors. The JMX Agent will have been enabled in order to provide local monitoring and management using a JMX Client. As mentioned in the introduction to this article, J2SE 5.0 comes with the JConsole application. JConsole provides a useful set of features that exercise the JMX capabilities for monitoring and managing your application as it runs. To run JConsole, enter the following at the command line:
The first thing that JConsole will attempt is to automatically locate all local (to the current machine) JMX Agents. If you have set things up correctly, the application you have just started should be automatically located and appear in the "JConsole: Connect to agent" dialog box, as shown in Figure 3.
Figure 3. The JConsole "Connect to Agent" dialog showing a local application that can be connected to
If you have problems connecting to local JMX Agents and you are using Windows, then check the format of your Windows boot partition according to the note in the Setting Up JMX section of this article.
Select your application from the list and click on Connect to start monitoring your application from within JConsole. By default, JConsole will then display a summary of your application's performance, as shown in Figure 4.
Figure 4. JConsole displaying a summary of a local application
You have now successfully connected to your application's JMX Agent using JConsole and can explore the facilities provided by JMX as exercised through JConsole's features. Click through the list of figures below to see some full-size screen shots that showcase some of the functions that JConsole supports.
One special and important feature of JMX, touched on in Figure 8, is the MBean. MBeans provide the mechanism by which you can embed custom management code into your application's management facilities in order to support interactions with your application through the JMX Agent. Any function that you want to expose within your application can be exposed as an MBean as long as you meet the MBean specification. The excellent book Java Management Extensions by J. Steven Perry walks you through how to create different types of MBeans to suit your application's management needs.
Due in part to the MBeans architecture, JMX is not simply a passive monitoring mechanism for Java applications. Through the use of MBeans you can also invoke operations on the applications being monitored, and even potentially receive notifications. Figure 10 shows how the standard Memory MBean provides the
gc() method that can be invoked in order to manually request that garbage collection should occur on the monitored application.
Figure 10. JConsole invoking the
gc() method on the standard Memory Management MBean
You have now effectively enabled and monitored the simple example application locally. The next step is to perform the same monitoring from a remote machine, giving you the ability to monitor any number of remote applications and services using JConsole.
The JConsole application itself uses up significant system resources, and so using the JConsole locally to the applications being monitored can have an impact on the monitored results. The preferred route for using JConsole is to start it from a remote machine and then, using the JMX remote monitoring facilities, log in to your application and monitor its performance from a safe distance.
As it happens, configuring JMX in order to monitor an application remotely is simple and elegant if security is not a big concern (if you are working in a development environment, for example).
To start the example application with remote monitoring enabled, no security options, and using an arbitrary free port of your choice, you need to add the
com.sun.management.jmxremote.ssl Java system properties to the command line:
> java -Dcom.sun.management.jmxremote \ -Dcom.sun.management.jmxremote.port=8004 \ -Dcom.sun.management.jmxremote.authenticate=false \ -Dcom.sun.management.jmxremote.ssl=false \ -classpath
When you now start JConsole from a remote networked machine, you should now be able to connect to the JMX agent in your application by entering the relevant information under the "Connect to Agent" dialog's "Remote" tab, as shown in Figure 11.
Figure 11. Connecting to a remote JMX-enabled application without authentication
At this point, you should only need to specify the Host or IP and the Port to connect to your application. The User Name and Password fields are not required, as you have not yet enabled authentication on your JMX Agent. Once the remote connection to your application's JMX Agent has been established, the title bar of JConsole will show the remote connection's details, as shown in Figure 12.
Figure 12. The remote connection's information displayed in JConsole's title bar
The fact that anyone can effectively manage your application at this point should be making you suitably nervous. The first step in securing the JMX Agent on your application is to add user name and password authentication. In order to enable JMX authentication, you first need to create a password file. A default template of the password file is located at %JRE_HOME%/lib/management/jmxremote.password.template.
Copy the template password file from %JRE_HOME%/lib/management/jmxremote.password.template to a directory that only you can read and write from (especially if you are working in a multiple-user environment). Your home directory is a good candidate location to copy the template password file to, renaming it %MY_HOME_DIRECTORY%/jmxremote.password.
Once you have created your own copy of the password file, amend its contents by un-commenting the two existing users monitorRole and controlRole. The resulting contents of your password file should look like this:
monitorRole QED controlRole R&D
R&D values are the cleartext passwords for the two roles. Once you have saved your changes, you can enable authentication in your application's JMX Agent when you run your application by setting the
com.sun.management.jmxremote.password.file Java system property to your amended
jmxremote.password file, and by setting the
com.sun.management.jmxremote.authenticate Java system property to
> java -Dcom.sun.management.jmxremote \ -Dcom.sun.management.jmxremote.port=8004 \ -Dcom.sun.management.jmxremote.authenticate=true \ -Dcom.sun.management.jmxremote.ssl=false \ -Dcom.sun.management.jmxremote.password.file=%MY_HOME_DIRECTORY%/jmxremote.password \ -classpath
Once your application has started, you can connect to the JMX Agent using JConsole by entering the remote monitoring information as before, but this time including one of the user names and passwords from your jmsremote.password file; for example, the "controlRole" user and the "R&D" password shown in Figure 13.
Figure 13. Connecting to a remote JMX-enabled application with authentication enabled
Once the remote connection to your application's JMX Agent has been established, the title bar of JConsole will show the remote connection's details, including the role you with which you connected, as shown in Figure 14.
Figure 14. The remote connection's information, including the user role, displayed in JConsole's title bar
At this point, it is worth changing the passwords that are stored in your copy of the jmxremote.password file. The file contains a set of simple
<role> <password> pairs. To change the passwords, simply edit the file and restart your application. For example, to change the password for the "controlRole" to "BANANA", edit your jmxremote.password file so that it contains:
monitorRole QED controlRole BANANA
Note: You can add new users with different permissions by editing the %JRE_HOME%/lib/management/jmxremote.access file. This is explained in more detail in the documentation on JMX available from Sun; see the References section of this article for details.
You have now effectively applied access authentication to your JMX-enabled application. However, the level of security that you have achieved is probably only acceptable for a development environment, as the passwords are still being exchanged in cleartext form between your application's JMX Agent and clients such as JConsole. Although it is beyond the scope of this article, it is worth considering using the SSL configuration options that are built into JMX in order to secure remote JMX monitoring in any production environments.
This completes the whirlwind tour of JMX and JConsole and how to monitor your own applications locally and remotely. The combination of JMX 1.2 and JConsole in J2SE 5.0 brings Java application management and monitoring to the front line of Java development like never before. There is much more to JMX, including the capability to programmatically create your own clients and your own MBeans, and so it is definitely worth digging a little deeper into what JMX 1.2 has to offer by exploring the references provided with this article.
Russell Miles is a senior consultant for SpringSource in the UK and contributes to various open source projects while working on books for O'Reilly.
Return to ONJava.com.
Copyright © 2009 O'Reilly Media, Inc.