Using JMX within a spring application

Posted: March 3, 2012 in Java Posts
Tags: , , , , ,

Lately I have been doing a lot with JMX. I use it more and more to check what my application is doing. I use it to monitor tomcat, the cache, queue’s and other libraries and components. Now I wanted to use jmx to monitor my own application. Using the standard JMX stuff coming with the JDK is not hard, but since I use a lot of spring, I wanted to know more about spring support.

The most important question in the end will be, is it easier to use spring with jmx than the standard jmx stuff from the jdk.

Read on to find out about jmx and my answer to the question which is easier, the spring way or the standard jmx way.

 

Background

Java Management Extension was introduced to create a uniform way to manage your java applications. A very basic console was introduced jConsole. You can now monitor the cpu usage of the jvm, memory consumption and lots of other characteristics. Frameworks and tools like tomcat, ActiveMQ and EHcache provided a lot of information through jmx.

Allard has written a whitepaper about jmx that you can find on the jteam website:

http://www.jteam.nl/dms/whitepapers/JavaApplicationMonitoringAndManagement.pdf

I want to have a better look at providing your own management information through jmx. For a project I was interested in the internals of a connection pool. I wanted to learn about the amount of active connections, the idle connections, passivations and activations. For the Axon Framework we wanted to have a better insight in the amount of event listeners, command handlers, received events and handled commands. For Axon we want to use as little springframework as possible and for the other project with the connections pool I want the easiest solution.

I big advantage of jmx is that you are able to use a generic client to access it. Disadvantage is that you must have this generic client and that firewalls must enable you to connect to the jmx server. Therefore I want to have a very basic web client that provides the most basic jmx information through a web interface.

Introducing the example

The sample is a very basic service that is used to store contacts. The service provides a statistics object that keeps data about the amount of stored contacts. If you are looking for code, check the code at my source repository at google code.

http://code.google.com/p/gridshore/source/browse/#svn/trunk/JMXMonitor

MBeans the jdk way

The jdk comes with jmx out of the box. It is not hard to use. You must create an interface that ends with MXBean or use the annotation. Of course there must be an implementation as well. The implementation is than used to manage facets of your application. In our example we expose one parameter, the amount of registered contacts. The implementation uses the ContactServiceStatistics from the the ContactService. This statistics object exposes the amount of registered contacts.

Now we need to actually do something with jmx. There are two major steps:

  1. Obtain the platform mbeanserver
  2. Register the MXBean with the mbeanserver

Now we can interact with the service by adding contacts. Using the jdk provided jmx client, we can see the amount of registered contacts. The following code block shows the code for the Runner class that executes the example and provides the command line interface to add new contacts.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
public class Runner {
    public static void main(String[] args) throws Exception {
        MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();
        ContactService service = new InMemoryContactService();
        ContactServiceMonitorMXBean mbean = new ContactServiceMonitor(service);
        ObjectName monitorName = new ObjectName("Gridshore:name=contactServiceMonitor");
        mbeanServer.registerMBean(mbean, monitorName);
        String input = "";
        do {
            System.out.println("Type stop if you want to, well euh, stop !");
            input = (new BufferedReader(new InputStreamReader(System.in))).readLine();
            service.addContact(new Contact(0, input));
        } while (!"stop".equals(input));
    }
}

The amount of code is oke, not very hard to implement. The following image gives a screendump of jconsole with the MXBean in it. Notice the location of the MXBean. The ObjectName is used to determine the location for the bean. The configured name is “Gridshore:name=contactServiceMonitor” which can easily be identified in the jconsole image.

jconsole screendump from runner without jdk

MBeans the spring way

Now let us have a look at what spring can do for us when doing jmx. The support for jmx from spring is extensive. A complete section in the reference manual is dedicated to jmx. We are only touching a small part, but an important part. You can find out more about the spring jmx way here:

http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/jmx.html

If you know your way with spring, the first thing that comes to mind is xml. Oke, nowadays a lot of annotations make life easier. With spring, the jdk way to find the mbeanserver and to register the beans is made easier. The javacode is replaced with some xml and annotations. I agree that in this specific case with the very basic sample the jdk way might even look easier. Still it fit’s nice with our own spring applications and there is a very big advantage using spring. That is when you want to create your own client. Spring comes with something nice to support that, this is explained in the next section.

The spring solution again consists of an interface and an implementation. The interface is actually only used for the client, so we could do with only the java class. Than we need an xml config file with only two items:

1
2
3
4
<beans>
    <context:component-scan base-package="nl.gridshore.monitoring"/>
    <context:mbean-export registration="replaceExisting"/>
</beans>

The runner now becomes incredible easy. The following lines of code show the complete runner

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
public class Runner {
    public static void main(String[] args) throws IOException {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
                "nl/gridshore/monitoring/springannotation/spring-config.xml");
        ContactService service = context.getBean(ContactService.class);
        String name = "";
        do {
            System.out.println("Type stop if you want to, well euh, stop !");
            name = (new BufferedReader(new InputStreamReader(System.in))).readLine();
            service.addContact(new Contact(0,name));
        } while (!"stop".equals(name));
    }
}

Now the jconsole looks like the following image. Check that we now have an additional folder in the folder tree. This is the type of the bean that is registered with the mbeanserver. More on this name when we discuss the client.

jconsole while running the spring runner

JMX clients

Nice to show the data through the jconsole application. There is a catch. Of course you need to have java to start the console. But you also need to explicitly enable it for remote access. Usually this mean firewall changes. Not the easiest way. If you want basic information it might be easier to create a client yourself.

Of course the jdk comes with client capabilities as well. I did however not spend a lot of time looking at them. With spring it becomes so easy to create a client that I only look at the spring way to create a client. Check out the following page if you want more information.

http://java.sun.com/docs/books/tutorial/jmx/remote/custom.html

Spring proxy

Spring comes with a class that acts as a proxy to an MBean. This can be a bean of yourself, a bean provided by a library but also a bean running in a remote jmx server. The following lines show the addition xml configuration for the proxy. You need an interface that is implemented by the proxy. It is easy if the MXBean implements this interface, but as long as the methods are available it is not required. Using this interface you can inject the proxy into another class, the JMXTestClient. Which in itself can be a controller or a service in your own application.

1
2
3
4
5
<bean id="proxyContactServiceMonitor" class="org.springframework.jmx.access.MBeanProxyFactoryBean">
    <property name="objectName"
              value="nl.gridshore.monitoring.springannotation:name=contactServiceMonitorSpring,type=ContactServiceMonitorSpring"/>
    <property name="proxyInterface" value="nl.gridshore.monitoring.springannotation.ContactServiceMonitor"/>
</bean>

Have a good look at the value for objectName. It consists of the package name of the class that is registered as an mbean. The name is is the registeren spring bean name and the type is the actual class name.

Now the client becomes very easy. The following code block shows the client as well as the new Runner class that makes use of the client.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
@Component("client")
public class JmxTestClient {
    private ContactServiceMonitor contactServiceMonitor;
    public int obtainAmountOfContact() {
        return contactServiceMonitor.getAmountOfContacts();
    }
    @Autowired
    public void setContactServiceMonitor(@Qualifier("proxyContactServiceMonitor")ContactServiceMonitor contactServiceMonitor) {
        this.contactServiceMonitor = contactServiceMonitor;
    }
}
public class Runner {
    public static void main(String[] args) throws IOException {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("nl/gridshore/monitoring/springannotation/spring-config.xml");
        ContactService service = context.getBean(ContactService.class);
        String name = "";
        do {
            int amountOfContacts = context.getBean(JmxTestClient.class).obtainAmountOfContact();
            System.out.println("Amount of contacts now is : " + amountOfContacts);
            System.out.println("Type stop if you want to, well euh, stop !");
            name = (new BufferedReader(new InputStreamReader(System.in))).readLine();
            service.addContact(new Contact(0,name));
        } while (!"stop".equals(name));
    }
}

The following code block shows you a screendump of a jmx client that is used to monitor the amount of items and sessions in a connection pool as well as basic information about the cache in use.

Screen shot 2010-06-02 at 21.39.50.png

Conclusion

I like the way spring helps you in hiding some complexity. To be honest with these simple examples spring is not less code than with the plain jdk way of jmx interaction. But if the amount of beans increase, to my opinion spring becomes easier. If you are already creating a spring application I would also do the spring way, it just fits better.

Advertisements
Comments
  1. Raymond Antony says:

    Good explanation

  2. Demarcus Weldon says:

    Wohh just what I was searching for, thanks for posting.

  3. elektroninen tupakka suomesta says:

    Really good information can be found on site.

  4. a2263638 says:

    I’ve said that least 2263638 times. SCK was here

  5. certified nursing assistant exam says:

    Thanks for sharing excellent informations. Your site is so cool. I am impressed by the details that you’ve on this blog. It reveals how nicely you perceive this subject. Bookmarked this website page, will come back for more articles. You, my pal, ROCK! I found just the information I already searched all over the place and just couldn’t come across. What an ideal site.

  6. teething bling pendant donut shaped moonstone says:

    I really enjoy studying on this site, it holds good blog posts. “A short saying oft contains much wisdom.” by Sophocles.

  7. music licensing website says:

    I like this blog very much, Its a rattling nice billet to read and get info. “Some people are so afraid to die that they never begin to live.” by Henry Van Dyke.

  8. cartoon basketball babies says:

    A person essentially assist to make critically articles I would state. This is the first time I frequented your website page and up to now? I surprised with the research you made to make this actual put up incredible. Great task!

  9. music licensing service says:

    I like this web blog it’s a master piece! Glad I observed this on google.

  10. cheap vacations says:

    I’ve been browsing online greater than three hours today, yet I by no means discovered any fascinating article like yours. It is lovely price enough for me. Personally, if all web owners and bloggers made excellent content as you probably did, the net shall be a lot more useful than ever before.

  11. black hat seo says:

    I’ve been absent for some time, but now I remember why I used to love this website. Thanks , I will try and check back more often. How frequently you update your web site?

  12. kettlebell squat clean says:

    Hi! I’ve been following your website for a long time now and finally got the bravery to go ahead and give you a shout out from Lubbock Tx! Just wanted to say keep up the good job!

  13. seo says:

    Real nice pattern and excellent subject material, very little else we require :D.

  14. west virginia wheels basketball says:

    My partner and I absolutely love your blog and find almost all of your post’s to be exactly I’m looking for. can you offer guest writers to write content for yourself? I wouldn’t mind writing a post or elaborating on a few of the subjects you write about here. Again, awesome website!

  15. Luigi Namm says:

    Some truly nice and useful information on this site, likewise I conceive the design has good features.

  16. attorney anchorage says:

    Keep up the superb piece of work, I read few articles on this web site and I conceive that your web blog is really interesting and has lots of great information.

  17. kore dizileri izle says:

    Hello admin great put up much thanks liked this web site seriously much

  18. fourmicroonde says:

    Precisely what I was looking for, regards for posting . “Pardon one offense, and you encourage the commission of many.” by Publilius Syrus.

  19. website templates says:

    I like this website very much so much wonderful information. “It’s a poor sort of memory that only works backward.” by Lewis Carroll.

  20. accelerated nursing programs says:

    Heya i’m for the primary time here. I found this board and I in finding It truly useful & it helped me out a lot. I hope to offer something back and aid others like you aided me.

  21. eliminating credit card bills says:

    My brother suggested I might like this website. He was once entirely right. This put up truly made my day. You cann’t imagine simply how so much time I had spent for this information! Thank you!

  22. Caryl says:

    I like this website very much, Its a really nice office to read and receive info. “Some people are so afraid to die that they never begin to live.” by Henry Van Dyke.

  23. bus travel illinois says:

    I have recently started a web site, the information you offer on this site has helped me greatly. Thank you for all of your time & work.

  24. fans for you and me says:

    There is evidently a lot to identify about this. I consider you’ve made the right points in features also.

  25. I have been surfing online greater than 3 hours today, yet I by no means discovered any attention-grabbing article like yours. It’s lovely value enough for me. Personally, if all webmasters and bloggers made good content material as you probably did, the web shall be a lot more helpful than ever before.

  26. Backlinks to Backlinks says:

    Thank you for the good writeup. It actually was a leisure account it. Glance complicated to far introduced agreeable from you! However, how could we keep up a correspondence?

  27. Eva Angelina says:

    Rattling nice design and wonderful articles, absolutely nothing else we want :D.

  28. final fantasy rom says:

    Very interesting subject, regards for putting up.

  29. resorts in Kissimmee Florida says:

    Very interesting info!Perfect just what I was looking for!

  30. Bobbie Mcgrevey says:

    I am starting my own blog and would like to know if you could help me get started. You can contact me at timm@allinonerestoration.com

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s