Exposing Spring Beans as JMX Managed Beans in Tomcat

Steve Neal Development, Java Programming 4 Comments

JMX provides a simple solution to application management. In this article, we’ll look at how Spring beans can be easily exported as a JMX MBean making their methods and properties available from a JMX client application, such as JConsole.

This technique has the following advantages:

  • Your Java bean’s methods can be triggered manually and interactively (great for application development and management)
  • Has minimal impact on the code you write (only annotations are used)
  • Simple to configure using Spring
  • Works for stand-alone applications and server based ones too (the following discussion demonstrates this using Tomcat)

What are JMX and Spring?

JMX provides a standard means of accessing, and interacting with, objects within a running process. An object that exposes itself via JMX is known as an MBean, if you’re looking for a more detailed overview of JMX, try this excellent introductory article on JMX by Brian Goetz.

Spring is a comprehensive open-source framework which can greatly simplify the development of all types of Java applications

In this article, a basic understanding of both JMX and Spring is assumed.

Configuring Spring

There are a few ways of doing this. This is my favourite approach though as it is the least invasive to your Java code (as you’ll see later on) :

<!-- Expose all annotated beans as JMX MBeans -->

<bean id="exporter"

      lazy-init="false"
      p:autodetectModeName="AUTODETECT_ASSEMBLER"
      p:assembler-ref="assembler"
      p:namingStrategy-ref="namingStrategy"/>

<bean id="assembler"

      p:attributeSource-ref="annotationAttributeSource"/>

<bean id="namingStrategy"

      p:attributeSource-ref="annotationAttributeSource"/>

<bean id="annotationAttributeSource"
     />

The exporter will identify which of your application classes should be exported as JMX beans. If your application classes support the JMX management interfaces then this class can be used to detect and export your beans automatically for you (just set the autoDetectModeName property to AUTODETECT_MBEAN).

A simpler approach, which relies on you simply annotating your POJO classes, is to configure the exporter to use an assembler (to identify which beans should be exported) and a naming strategy (to decide what names will be used for your beans when they are exported to the JMX server). Note in the above example how the assembler and namingStrategy properties have been set to use this approach.

Both the assembler and the namingStrategy delegate their method calls to the annotationAttributeSource bean (c.f. the Strategy design pattern) which examines the beans in the Spring context for annotations to determine whether the beans are to be exported and what their names should be respectively.

Annotating Your Java Code

So now that Spring is configured to look for annotated classes, all you need to do is annotate your classes to indicate whether they should be exported as JMX services:

@ManagedResource(objectName="bean:name=BatchProcessor")
public class BatchProcessor {

    @ManagedOperation
    public void startBatch() {

    }
}

The ManagedResource annotation indicates that this class should be exported, and the objectName attribute specifies the JMX bean name.

The ManagedOperation annotation should be used to indicate which methods on this class should be accessible via JMX; by default methods are not made available. Both of the above annotations allow for general information to be set too, for example a description of the bean or the method.

Configuring the Java Runtime

Any J2SE 5 (or later) runtime provides support for JMX. In order to use it, certain system properties must first be set.

For example, if you wanted to activate JMX in Tomcat, then you’d need to add these system properties to the start-up script:

set CATALINA_OPTS=-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=8086
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false

In this example, no security has been set for the Tomcat process. You should ensure that you configure JMX appropriately for your environment.

Using JConsole to Access Your MBeans

JConsole is an application that ships with the current JDK from Sun. It provides a graphical user interface for accessing JMX beans running in remote processes.

You can launch JConsole from the command line:

$ jconsole

When it starts, you’ll be asked to enter a URL for the JMX server you want to attach to. The above configuration specified that the JMX port should be 8086. If you’ve used the same configuration, then, once Tomcat has started, enter localhost:8086 and click on the Connect button.

Once connected, you can examine the JMX beans. Different versions on JConsole present these differently, the current version lists them under the MBeans tab, and under the beans node in the tree shown on the left. From here you can interactively invoke the methods on your beans and set or get their properties.

Conclusion

Exposing your application services in JMX provides a simple and effective means of accessing functionality that would only otherwise be available to the running application. This is particularly useful when manual intervention is sometimes required; for example, to manually launch a batch processor that’s embedded in the application.

Comments 4

  1. tim anderson

    Great article. I used the system properties you describe to setup JMX in Tomcat and it worked, so thank you so much. I’ve been looking for tomcat jmx resources and unfortunately not much comes up. The page I linked to doesn’t really have any content. But your blog post is great, thanks.

  2. Beppe

    Nice post :-)

    I have just started with JMX and I would like to publish a collection of properties, with a standard MBean I can code each single property with getter/setter, but how do I avoid this?
    Is there a way to expose properties which are backed by a collection?

    Tnx

  3. Steve Neal


    Beppe:

    Nice post
    I have just started with JMX and I would like to publish a collection of properties, with a standard MBean I can code each single property with getter/setter, but how do I avoid this?
    Is there a way to expose properties which are backed by a collection?
    Tnx

    Not that I’ve come across. Why do you want to avoid getters and setters? They are a standard programming model in Java. Plus any IDE will create them automatically for you anyway. I generally have a section in a class that contains IDE generated methods that I can completely delete and regenerate when I want too – have you considered this approach?

Leave a Reply

Your email address will not be published. Required fields are marked *