Tag Archives: ehcache

EHCache, JMX, Hibernate and Spring

We have a spring/hibernate application that we also like being able to use JConsole with, so we expose a few things via jmx.  Spring makes this pretty easy for the most part, you just use @ManagedResource on with the boiler plate config below, you’re good to go!

    <!-- Allow any bean to be exposed as an mbean.  Just use @ManagedResource and @ManagedAttribute -->
    <bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
        <property name="assembler" ref="assembler"/>
        <property name="namingStrategy" ref="namingStrategy"/>
        <property name="autodetect" value="true"/>
        <property name="registrationBehaviorName" value="REGISTRATION_IGNORE_EXISTING"/>
    </bean>
    <bean id="attributeSource" class="org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource"/>
    <bean id="namingStrategy" class="org.springframework.jmx.export.naming.MetadataNamingStrategy">
        <property name="attributeSource" ref="attributeSource"/>
    </bean>
    <bean id="assembler" class="org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler">
        <property name="attributeSource" ref="attributeSource"/>
    </bean>

But what about exposing beans from libraries?  For hibernate it’s easy, you just make spring create the hibernate provided bean…

    <bean id="hibernateStatistics" class="org.hibernate.jmx.StatisticsService">
        <property name="statisticsEnabled" value="true"/>
        <property name="sessionFactory" ref="nipSessionFactory"/>
    </bean>

and then modify your mbean exporter config to specifically include hibernate stats…

    <bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
        <property name="assembler" ref="assembler"/>
        <property name="namingStrategy" ref="namingStrategy"/>
        <property name="autodetect" value="true"/>
        <property name="registrationBehaviorName" value="REGISTRATION_IGNORE_EXISTING"/>
        <property name="beans">
            <map>
                <entry key="Hibernate:name=statistics" value-ref="hibernateStatistics"/>
            </map>
        </property>
    </bean>

Presto, hibernate stats are now available in Jconsole, wherever you specify with the key. Well and good. But what about EHCache? According to http://ehcache.org/documentation/jmx.html there’s mbeans provided here too, so we can just list them in our bean config and add them to the list with hibernate right? MAYBE! You can get the cache manager working like this…

    <bean id="cacheManager" class="net.sf.ehcache.management.CacheManager">
        <constructor-arg ref="innerCacheManager"/>
    </bean>
    <bean id="innerCacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
        <property name="shared" value="true"/>
    </bean>

and then refer to cacheManager in the list of beans to export. But when it comes to the CacheStatistics object, you need to somehow get at the EhCache object itself, and spring bean config doesn’t have any way of getting at that easily.

Instead, you can just ask EhCache to register itself with the mbean server. This is covered at http://forum.springsource.org/showthread.php?t=63453 but I just wanted to cover it with a bit more information…

The extra beans you need for full EhCache jmx management, on top of the hibernate stats config above is:

    <!-- only needed explicitly because ehcache needs it to register itself -->
    <bean id="mbeanServer" class="org.springframework.jmx.support.MBeanServerFactoryBean">
      <property name="locateExistingServerIfPossible" value="true"/>
    </bean>
 
    <!-- ehcache needs to register itself, we can't just give the bean to jmx ourselves -->
    <bean id="ehCacheMBeanRegistration" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
        <property name="staticMethod" value="net.sf.ehcache.management.ManagementService.registerMBeans"/>
        <property name="arguments">
            <list>
                <ref bean="innerCacheManager"/>
                <ref bean="mbeanServer"/>
                <value>true</value>
                <value>true</value>
                <value>true</value>
                <value>true</value>
            </list>
        </property>
    </bean>
    <bean id="innerCacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
        <property name="shared" value="true"/>
    </bean>