Tuesday, June 22, 2010

Enabling JMX Monitoring for Spring-JPA-Hibernate Application

Requirement: Be sure that the application correctly utilizing second level caching by using ehcache. And what is the cache utilization level for the application?
Technologies that is used in the appilcation: JPA/Hibernate, Spring 2.5, JSF+Richfaces.
After some googling I understood that the only way to get caching utilization is to monitor it by JMX.  My collegue Ray McDermott came to the resque and sent me the article:
which I inspired form.
I assume that you have already a similar application. So I will not go through the how you can create such kind of project. If you want to create an application from scratch please read the article above.
To enable caching statistics in your Spring-JPA/Hibernate application first set the hibernate parameters in persistence.xml  like:
<property name="hibernate.cache.provider_class" value="net.sf.ehcache.hibernate.SingletonEhCacheProvider"/>
<property name="hibernate.cache.use_query_cache" value="true"/>
<property name="hibernate.jdbc.wrap_result_sets" value="true"/>
<property name="hibernate.cache.use_minimal_puts" value="false" />
<property name="hibernate.cache.use_second_level_cache" value="true" />
<property name="hibernate.cache.use_structured_entries" value="true" />
<property name="hibernate.generate_statistics" value="true" />
Second, we need configure JMX Monitoring aspects:
Simply we need to create two aspects:
  • JMX MBean - which can represent a device, an application, or any resource that needs to be managed.
  • JMX Agent - which is an application that registers MBean(s) with a MBeanServer, e.g. the platform MBeanServer.

In this case we do not need to create JMX Mbean since it will be provided by Hibernate.
We need a JMX Agent:
import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.persistence.EntityManagerFactory;

import net.sf.ehcache.CacheManager;
import net.sf.ehcache.management.ManagementService;

import org.hibernate.SessionFactory;
import org.hibernate.ejb.HibernateEntityManagerFactory;
import org.hibernate.jmx.StatisticsService;

public class JmxAgent {

      private EntityManagerFactory entityManagerFactory;
      private MBeanServer mbs;

      public void init() throws Exception {

            SessionFactory sf = ((HibernateEntityManagerFactory) entityManagerFactory)
                        .getSessionFactory();

            ObjectName on = new ObjectName(
                        "Hibernate:type=statistics,application=flrs-web");

            StatisticsService statsMBean = new StatisticsService();
            statsMBean.setSessionFactory(sf);
            statsMBean.setStatisticsEnabled(true);
            mbs.registerMBean(statsMBean, on);

            CacheManager cacheMgr = CacheManager.getInstance();
            ManagementService.registerMBeans(cacheMgr, mbs, true, true, true, true);
      }

      public MBeanServer getMBeanServer() {
            return mbs;
      }

      public void setEntityManagerFactory(
                  EntityManagerFactory entityManagerFactory) {
            this.entityManagerFactory = entityManagerFactory;
      }

      public void setMbs(MBeanServer mbs) {
            this.mbs = mbs;
      }

}
JMXAgent is Spring aware bean and init() is the initializing method for that bean.  JMXAgent has two properties:
MbeanServer ‘mbs’ and EntityManagerFactory  ‘entityManagerFactory’ which are injected by the spring during appilcation context creation.
Here is the Spring configuration of JMXAgent:
<bean id="mbeanServer" class="java.lang.management.ManagementFactory"
      factory-method="getPlatformMBeanServer" />
     
<bean id="jmxAgent" class="com.xxx.flrs.view.utility.JmxAgent" init-method="init">
      <property name="entityManagerFactory" ref="entityManagerFactory"/>
      <property name="mbs" ref="mbeanServer"/>
bean>
That’s all you need to do in the application.
After you complete the application modification, deploy the JMX enabled version in your application server. I tried in Glassfish v2.1.1. But no matter which application server you used. Just be sure that if JMX is enabled for your application server.
And finally here is the funniest part, Monitor hibernate statistics:
To do that first open Jconsole. If %JAVA_HOME% /bin folder is in you path, just open command prompt and type jconsole. You will be asked for a connection:

Find the Advanced tab and type the JMX Url of your application server. Username and Password is the same pair that you login administration console for Glassfish.
I tried other Local and Remote connection ways but i was not sucessfull.
If everything goes right, you should see the window:

Find the Mbeans tab and here is the Hibernate Statistics:





Thank You