Nov 09

5 Minute Guide to Spring and JMX

Tag: java,jmx,springpmularien @ 10:30 am

I recently augmented a Spring-based project to expose some of the Spring-managed beans via JMX. Spring makes this very easy, and even if you’ve never used JMX before, this quick tutorial will let you set up your Spring beans to be viewed (and edited!) through a JMX console.

Prerequisites

  1. Make sure you have a recent version of Spring (I used Spring 2.5 RC 1, but Spring 2.0.x will do).
  2. Make sure you have a recent version of Java, ideally Java 6.
  3. You should try to have an existing Spring application that you can follow along with, deployed in an app server that has built-in JMX support (i.e. has an MBean server that you can reuse). I use Tomcat 6 in this walk-through.

Cook-Along

Add the following to your Spring XML configuration file:

<bean id="exporter"
 class="org.springframework.jmx.export.MBeanExporter"
 lazy-init="false">
  <property name="autodetect" value="true"></property>
  <property name="namingStrategy" ref="namingStrategy"></property>
  <property name="assembler" ref="assembler"></property>
</bean>
<bean id="attributeSource"
 class="org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource"/>
<bean id="assembler"
 class="org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler">
  <property name="attributeSource" ref="attributeSource"/>
</bean>
<bean id="namingStrategy"
 class="org.springframework.jmx.export.naming.MetadataNamingStrategy">
  <property name="attributeSource" ref="attributeSource"/>
</bean>

This will set up a Spring-managed JMX configuration with the following attributes:

  • Using an existing MBean server
  • Auto-detecting beans with the @ManagedResource annotation
  • MBean naming defined by the “objectName” attribute of the @ManagedResource annotation

For a Java 5 deployment of Spring, these seem reasonable, and I’m surprised that they aren’t the default configuration for Spring 2.5.

Next, we’ll need to annotate our spring-managed bean with the @ManagedResource annotation. The simplest possible usage is as follows:

@ManagedResource(objectName = “bean:name=simpleBean”, description = “A sample JMX-managed bean”)

This annotation is done at the class level – Spring will auto-detect beans with this annotation and register them as MBeans with the MBean server. The next (and final) step in the tutorial is to select which attributes of our MBean that we’ll expose. We do this by annotating members (or getters and setters) with the @ManagedAttribute annotation. So our final Java code for a simple bean looks like this:

package com.mularien.jmx;
 
import org.springframework.jmx.export.annotation.ManagedAttribute;
import org.springframework.jmx.export.annotation.ManagedResource;
 
@ManagedResource(objectName = "spring:name=simpleBean", description = "A
sample JMX-managed bean")
public class SimpleBean {
 public String url;
 
 @ManagedAttribute
 public String getUrl() {
  return url;
 }
 public void setUrl(String url) {
  this.url = url;
 }
}

And now you’re done! Fire up jconsole and connect to the Tomcat server. You’ll see a JMX namespace called “spring” with the simpleBean MBean in it.

Hopefully this was a helpful introduction on how to use JMX with your Spring beans. Spring provides a whole lot of flexibility in this area, but I wanted to write this simple tutorial, as I didn’t see one that I liked already online. Enjoy (and please comment if you found this helpful/not helpful)!

Further Reading

Rob Harrop covers Spring and JMX integration well with a series of slides in his blog (warning: many spammy comments!).

The Spring documentation is a great resource (as always) with its extensive coverage of JMX and Spring.

Sun provides Essentials of the JMX API, which is a good, brief overview of JMX and MBeans.

19 Responses to “5 Minute Guide to Spring and JMX”

  1. napyfab:blog» Blog Archive » links for 2007-11-15 says:

    […] It’s Only Software » 5 Minute Guide to Spring and JMX (tags: spring jmx java bean development howto integration introduction programming guide tutorial) […]

  2. Vinny Carpenter’s blog » Daily del.icio.us for Nov 02 through Nov 23, 2007 says:

    […] It’s Only Software » 5 Minute Guide to Spring and JMX – I recently augmented a Spring-based project to expose some of the Spring-managed beans via JMX. Spring makes this very easy, and even if you?ve never used JMX before, this quick tutorial will let you set up your Spring beans to be viewed (and edited!) t […]

  3. Mark says:

    This example is incomplete. Doesn’t help much. You should include a complete example.

  4. pmularien says:

    @Mark

    What in particular are you looking for?

    Peter

  5. Goman says:

    Thank your very much. Nice work.

    i want to add additional information for those of you running JVM with non US settings(mine is tr(turkey)).
    Starting spring application without -Duser.language=en -Duser.region=US parameters you will get the following error messages in jconsole and will not connect the JVM. so i suggest adding these parameters.

    java.lang.reflect.UndeclaredThrowableException
    at $Proxy1.getVmName(Unknown Source)
    at sun.tools.jconsole.SummaryTab.formatSummary(SummaryTab.java:133)
    at sun.tools.jconsole.SummaryTab$1.doInBackground(SummaryTab.java:74)
    at sun.tools.jconsole.SummaryTab$1.doInBackground(SummaryTab.java:72)
    at javax.swing.SwingWorker$1.call(SwingWorker.java:278)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at javax.swing.SwingWorker.run(SwingWorker.java:317)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:885)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
    at java.lang.Thread.run(Thread.java:619)
    Caused by: java.io.IOException: The client has been closed.
    at com.sun.jmx.remote.internal.ClientCommunicatorAdmin.restart(ClientCommunicatorAdmin.java:74)
    at com.sun.jmx.remote.internal.ClientCommunicatorAdmin.gotIOException(ClientCommunicatorAdmin.java:34)
    at javax.management.remote.rmi.RMIConnector$RMIClientCommunicatorAdmin.gotIOException(RMIConnector.java:1422)
    at javax.management.remote.rmi.RMIConnector$RemoteMBeanServerConnection.getAttributes(RMIConnector.java:893)
    at sun.tools.jconsole.ProxyClient$SnapshotInvocationHandler.getCachedAttributes(ProxyClient.java:1038)
    at sun.tools.jconsole.ProxyClient$SnapshotInvocationHandler.getAttribute(ProxyClient.java:997)
    at sun.tools.jconsole.ProxyClient$SnapshotInvocationHandler.invoke(ProxyClient.java:979)
    at $Proxy0.getAttribute(Unknown Source)
    at com.sun.jmx.mbeanserver.MXBeanProxy$GetHandler.invoke(MXBeanProxy.java:106)
    at com.sun.jmx.mbeanserver.MXBeanProxy.invoke(MXBeanProxy.java:148)
    at javax.management.MBeanServerInvocationHandler.invoke(MBeanServerInvocationHandler.java:248)
    … 11 more

  6. yujia says:

    Just to add that it is important to use -Dcom.sun.management.jmxremote when you start tomcat, even if you are using Java 6. Otherwise you may not see your mbeans in jconsole. It seems that if -Dcom.sun.management.jmxremote is not specified, Tomcat will use its own mbean server rather then the platform mbean server.

  7. tore says:

    If you add @Component to your class SimpleBean, all you need in your Spring XML config file is this:

    <context:component-scan base-package="com.whatever.jmx" />
            <context:mbean-export/>
  8. Rodrigo says:

    Hi.

    Unfortunately, I could not get this example to work with JBOSS. I did everything in this guide, but the mbean did not appear in jmx-console.

    Regards,

    Rodrigo.

  9. AWied says:

    W00t! That was the easiest JMX integration ever. Thanks Peter!

    FYI – This is working with Spring 2.5.6 and JBossAS 5.0

  10. DGN says:

    Excellent tutorial. Got it working on Tomcat6 with a project that already had Spring integrated. Just created a simple bean class, added annotations, and was able to access it with JConsole. However, a couple of things not mentioned above that may be of help:

    1) Per Tomcat documentation on JMX added the following to CATALINA_OPTS environment setting:

    set CATALINA_OPTS=”-Dcom.sun.management.jmxremote \
    -Dcom.sun.management.jmxremote.port=%my.jmx.port% \
    -Dcom.sun.management.jmxremote.ssl=false \
    -Dcom.sun.management.jmxremote.authenticate=false”

    For %my.jmx.port% I set an arbitrary value of 22222. (Pick your own favorite number.)
    see: http://tomcat.apache.org/tomcat-6.0-doc/monitoring.html

    2) When starting JConsole I used the Remote Process (not local) and used the URL:
    service:jmx:rmi:///jndi/rmi://localhost:22222/jmxrmi

  11. Spring says:

    many thanks for this tutorial, I have follow this tutorial step by step but I can not see my bean in JConsole even when I lauch tomcat with option -Dcom.sun.management.jmxremote, on my logs I see that the bean was registered but I can not see it on JConsole, I am using JDk6, Tomcat 6:

    here is the log:
    10:20:09.250 INFO org.springframework.jmx.export.MBeanExporter – Registering beans for JMX exposure on startup
    10:20:09.250 DEBUG org.springframework.jmx.export.MBeanExporter – Autodetecting user-defined JMX MBeans
    10:20:09.265 DEBUG ngframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1 – Finished creating instance of bean ‘exporter’
    10:20:09.265 DEBUG org.springframework.beans.factory.support.AbstractBeanFactory – Returning cached instance of singleton bean ‘attributeSource’
    10:20:09.265 DEBUG org.springframework.beans.factory.support.AbstractBeanFactory – Returning cached instance of singleton bean ‘assembler’
    10:20:09.265 DEBUG org.springframework.beans.factory.support.AbstractBeanFactory – Returning cached instance of singleton bean ‘namingStrategy’

    Any one has an idea on the problem

    thank you in advance

  12. Richard says:

    Thanks for this example. I found I needed to do a couple of other things before I could get Tomcat, Eclipse, Spring and JMX to all work together. Anyone having problems getting set up may find this link useful, plus the following page on the same site:

    http://www.bigsoft.co.uk/blog/index.php/2009/01/19/allow-remote-jmx-management-for-tomcat

  13. Andy says:

    This was an amazing tutorial. Very precise and very effective.

  14. Mark says:

    Lovely, digestible tutorial, thanks! Works out of the box with Spring 2.5 + Jetty 7 + OS X JConsole.

  15. Ash says:

    Super stuff! I got my JMX running in under 5 mins. Thanks.

  16. Vijay says:

    Hi, Thanks for the article. I have a similar Mbean and it appears in JConsole. However I want to access the same bean (and the property) using a java client using JMXService url i am not able to get the retrive the mbean. I get an error saying object does not implement the interface. Can you please advice how can we access such Mbean.

    regards

  17. Robert Smith says:

    I like Rodrigo was not able to get this to show up in JBoss jmx-console.

  18. Raza says:

    If you do the above and still don’t see your MBeans, try accessing your application first. Spring doesn’t expose your MBeans until the application is accessed once to get the context initialized. After you have accessed the application you should be able to see your mbeans in jconsole.

  19. nicord says:

    You can use org.springframework.jmx.export.annotation.AnnotationMBeanExporter as a “Convenient subclass of Spring’s standard MBeanExporter, activating Java 5 annotation usage for JMX exposure of Spring beans”.

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>