Monitoring EHCACHE with JConsole

Technologies involved:
Programming Language – Java
Java Framework – Spring
Persistence Layer – Hibernate
Secondary Cache – EHCACHE
Application Server – Tomcat

Objective: Monitor hibernate cached objects using JConsole

Configuration required: Following are some configurations that are required.

It’s is considered good practice to split the spring application context into smaller files that perform a specific task. Hence I would recommend making one such file for doing database configuration. Following is the database-servlet.xml.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">

	<!-- LEC Data-source -->
	<bean id="dataSourceCap" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
		<property name="driverClassName" value="${jdbc.driver}"/>
        <property name="url" value="${lec.db.url}"/>
        <property name="username" value="${lec.db.username}"/>
        <property name="password" value="${lec.db.password}"/>
	</bean>

	<!-- Session Factory for LEC database -->
	<bean id="sessionFactoryLec" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
		<property name="dataSource" ref="dataSourceCap" />
		<property name="packagesToScan" value="au.com.afgonline.lec.model" />
		<!-- <property name="schemaUpdate" value="true" /> -->
		<property name="hibernateProperties">
			<props>
				<!-- <prop key="hibernate.show_sql">true</prop> -->
				<prop key="hibernate.format_sql">true</prop>
				<prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop>
				<prop key="hibernate.cache.region.factory_class">net.sf.ehcache.hibernate.SingletonEhCacheRegionFactory</prop>
				<prop key="hibernate.cache.use_second_level_cache">true</prop>
				<prop key="hibernate.cache.use_query_cache">true</prop>
				<prop key="hibernate.generate_statistics">true</prop>
			</props>
		</property>
	</bean>

	<!-- Transaction Manager for LEC -->
	<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
		<property name="sessionFactory" ref="sessionFactoryLec" />
	</bean>

	<!-- Hibernate Template -->
	<bean id="hibernateTemplateLec" class="org.springframework.orm.hibernate3.HibernateTemplate">
		<property name="sessionFactory" ref="sessionFactoryLec"></property>
		<property name="cacheQueries" value="true" />
		<property name="queryCacheRegion" value="REF_DATA"></property>
	</bean>

	<!-- JMX for ehcache -->
	<bean id="managementService"
			class="net.sf.ehcache.management.ManagementService"
			init-method="init"
			destroy-method="dispose">

			<constructor-arg ref="cacheManager"/>
			<constructor-arg ref="mbeanServer"/>
			<constructor-arg index="2" value="true"/>
			<constructor-arg index="3" value="true"/>
			<constructor-arg index="4" value="true"/>
			<constructor-arg index="5" value="true"/>

	</bean>

	<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
	  <property name="configLocation" value="classpath:ehcache.xml"/>
	  <property name="shared" value="true"/>
	</bean>

	<bean id="mbeanServer" class="org.springframework.jmx.support.MBeanServerFactoryBean">
      <property name="locateExistingServerIfPossible" value="true"/>
</bean>

</beans>

As you can see from the above configuration the spring framework provides a lot of help. Spring has in built support for EHCACHE Manager and also has a ready to use MBeanServer. Some things to be aware of are that when configuring the hibernate properties make sure that the hibernate.generate_statistics is set to true.

Another file of interest is the ehcache.xml which is shown as below:

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true"
    monitoring="autodetect" dynamicConfig="true">

<defaultCache
            maxElementsInMemory="200000"
            eternal="true"
            overflowToDisk="false"
            statistics="true"
            />

           <cache
			name="org.hibernate.cache.StandardQueryCache"
			maxEntriesLocalHeap="10000"
			eternal="true" >
				<persistence strategy="localTempSwap" />
			</cache>

</ehcache>

In the ehcache.xml pay special attention to the attribute statistics in the element defaultCache. This needs to be set to true as well.

With these configuration in place we are now ready to deploy our WAR file on the tomcat application server. Once the project is deployed to the application server you can connect to the tomcat using JConsole. However if the tomcat is a remote server, following few lines need to be added to the setenv.sh:

export JAVA_OPTS="$JAVA_OPTS \
-Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.port=8086 \
-Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.management.jmxremote.authenticate=false"

Alright all set to view statistics following are some JConsole screen shots that will show you how to connect and how to see the various statistics of ECACHE managed beans.

Connect to the remote server as show in the screen shot below: Make sure the port number is the same as the port number in the configuration shown above. Many developers type in 8080 and wonder why nothing is showing up.

Screen Shot 2013-09-24 at 11.15.37 AM

Once connected go to the MBeans tab as shown below: Notice the net.sf.ecache package. This is the package that we inspect to see out statistics. Maybe hit the deployed project a couple of times so that some objects can be cached so you can see some statistics in real time.

Screen Shot 2013-09-24 at 11.15.57 AM

The Following screen displays where to go in the ecache package to view statistics for cached objects. The below screen shot shows statistics for an object called “OutputProduct”

Screen Shot 2013-09-24 at 11.18.19 AM

All done. Hope this is helpful to someone.

Leave a comment