Skip to main content

Going beyond JDK 5.0's out-of-the-box management

Posted by emcmanus on June 5, 2006 at 7:28 AM PDT

JDK 5.0 allows you to make an application monitorable without
writing any extra code, using command-line properties such as
-Dcom.sun.management.jmxremote. But what if the behaviour
obtained using these properties isn't exactly what you want?

Monitoring available out of the box

JDK 5.0 (codenamed Tiger) introduced support for management and
monitoring through three important new features (among
others):

  • addition of the JMX and JMX Remote APIs into the platform;
  • definition of a new API to monitor the JVM itself
    (java.lang.management)

  • support for "out-of-the-box" management and monitoring.

Of these, the first two are standard features of J2SE 5.0,
while the last is a specific feature of the JDK from Sun (and any
other implementations that may have copied it).

"Out-of-the-box" management and monitoring means that you can
take an application as it is, "out of the box", without any code
that specifically deals with monitoring, and add a JMX agent to
it to make it monitorable. The full details are in the document
href="http://download.java.net/jdk6/doc/technotes/guides/management/agent.html">Monitoring
and Management Using The JMX API
. Typically you run
the application with a command line something like this:

java -Dcom.sun.management.jmxremote.port=9876
     -Dcom.sun.management.jmxremote.password.file=/some/path/jmxremote.password
     com.example.MyApp.Main

This causes your application to be run with a JMX agent
accessible on port 9876, but protected by password authentication
defined in the file /some/path/jmxremote.password.

Then you can connect with jconsole, and get an idea of what
your application is doing. href="http://weblogs.java.net/blog/mandychung/">Mandy Chung
(who also led the work on out-of-the-box management) describes
this in detail in the article href="http://java.sun.com/developer/technicalArticles/J2SE/jconsole.html">Using
JConsole to Monitor Applications
. Here's a picture from
that article to whet your appetite, if you're not already familiar
with jconsole:

alt="Snapshot of jconsole showing heap memory graph">

Going beyond what's available out of the box

The idea behind out-of-the-box management was that people
should be able to monitor their applications without having to
learn the href="http://download.java.net/jdk6/doc/api/javax/management/remote/package-frame.html">JMX
Remote API. Just set a couple of properties, and off you
go.

On the other hand, we didn't want to address every
configuration that everybody could possibly want. The available
properties can be used to create useful configurations, but our
idea at the time was that there would obviously be problems that
couldn't be addressed by setting these properties. We didn't
want to add a new property every time somebody ran into such a
problem, in effect creating a parallel version of the JMX Remote
API defined with properties rather than Java method calls.
Instead, we thought that people could start off using the
properties, and if they ran into a need that wasn't addressed by
the properties then they could switch over to writing code that
calls the JMX Remote API explicitly.

For example, here are some interesting things that you can't do
with the properties, but that you can do by using the JMX
Remote API:

  • Obtain the same functionality on JDK 1.4.

  • Rather than hardwiring a port number like 9876 (and risking
    port conflicts), make the JMX agent available on a free port
    chosen by the operating system, and communicate the port
    number to management clients.

  • On a machine with multiple network interfaces, only export
    the JMX agent on one of them.

  • Use a different access-control scheme than the one
    available through the com.sun.management.jmxremote.access.file
    property.

  • The remote connectivity works by creating an RMI registry on
    the given port number, and putting an href="http://download.java.net/jdk6/doc/api/javax/management/remote/rmi/RMIServer.html">RMI
    object in that registry that is the JMX agent that
    remote clients connect to. Properties allow you to protect
    this object with SSL, but in JDK 5.0 they didn't allow you
    to protect the RMI registry with SSL. (This functionality
    has been added in JDK
    6.)

However, it's become clear over time that we omitted something
important. Imagine somebody wants to monitor their app. They
study the documentation to figure out how to use the properties
to get what they want. This works fine at first. Then they
realize there's some problem they can't solve using the
properties. So now they're forced to throw away what
they've learnt about the properties, and study another document,
the JMX Remote API, to figure out how to obtain the same thing.
Bummer.

What's needed is a document that lets you figure out, given a
configuration defined using properties, how to achieve the same
configuration with code. Then you can fiddle with the code to
solve your problem. You only need to study what's needed for
this change, not what's needed to achieve the initial
functionality.

An omission rectified

Fortunately, my colleague href="http://blogs.sun.com/roller/page/lmalventosa">Luis-Miguel
Alventosa has now supplied exactly such a document in his
blog entry href="http://blogs.sun.com/roller/page/lmalventosa/20060602">Mimicking
the out-of-the-box JMX management agent in J2SE
5.0
. I expect a version of this to appear in a
future version of the JDK documentation, but in the meantime,
here I am giving it some href="http://www.wordspy.com/words/Googlejuice.asp">googlejuice.

By the way, the fact that you are writing code to use the JMX
Remote API still doesn't mean you have to change your
application code. You can either write a new main
method in a different class that calls the original
main after exporting the JMX agent; or you can use
an agent class as described in the documentation for href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/instrument/package-summary.html">java.lang.instrument and launch your application something like this:

java -javaagent:/some/path/myjmxagent.jar com.example.MyApp.Main
Related Topics >>