Saturday, March 26, 2011

Registering Jboss Cache with MBeanServer

Jboss Cache is an generic cache implemented in java and licensed under lgpl 2.1. Similar kind of implementations are also available from apache ( JCS - Java caching System ) and Oracle ( oracle coherence ). All caches are almost having similar features and provide enterprise-grade clustering solutions to Java-based frameworks.

JBoss cache is already being used in different enterprise solution and fully tested for robustness and performance. Though, a more powerful data grid platform "Infinispan" is already available from the same JBoss Community.

Here I will not go much details inside JBoss cache, as numerous tutorials/example codes are already available in net and JBoss also provides a very informative documentation for their cache. This blog will only cover a typical topic on how we can register Jboss cache with an Mbean server.

Before proceeding further, I will assume my reader has basic knowledge on JBoss Cache, Spring and JMX. Also, he should be able to setup the cache and run it successfully.

There are two ways to register JBoss cache with a MBeanServer
  1. Programmatic Registration
  2. Register as a spring bean
  • Programmatic Registration
The following code is self explanatory. It will create a cache with default configuration and start the cache. Then it will register the cache with platform MBeanServer. The for loop will add an object to the cache  in every 2 sec.


package com.ne;

import java.lang.management.ManagementFactory;

import javax.management.MBeanServer;
import javax.management.ObjectName;

import org.jboss.cache.Cache;
import org.jboss.cache.CacheFactory;
import org.jboss.cache.DefaultCacheFactory;
import org.jboss.cache.jmx.JmxRegistrationManager;

public class TestCache
{

      public static void main(String[] args) throws Exception
      {
            CacheFactory factory = new DefaultCacheFactory();
//          Cache cache = factory.createCache();
            Cache cache = factory.createCache();
            cache.start();
           
            MBeanServer mbserver = ManagementFactory.getPlatformMBeanServer();
            ObjectName oname = new ObjectName("jboss.cache:service=Cache");
            JmxRegistrationManager jmxManager = new JmxRegistrationManager(mbserver, cache, oname);
            jmxManager.registerAllMBeans();
           
            for(int i = 0 ; ; i++)
            {
                  String fqn = Integer.toString(i);
                  cache.put(fqn, i, i);
                  Thread.sleep(2000);
                  System.out.println("one node added : "+i);
            }
      }
}


There are several other ways to use createCache() api. Such as

            Cache cache = factory.createCache("cache-configuration.xml");

 cache-configuration.xml will contain the cache settings, such as cache modes ( local, replicated etc ),  cache loaders, eviction policies. All details are available in JBoss Cache documentation and discussion about these cache properties are out of scope of  this blog.

  • Register as a spring bean
The example which I am going to explain in this blog, is a modified form of the bean configuration written in JBoss Cache userguide. As I have mentioned earlier, basic understanding of spring ioc is required to understand this example.
 
At first, lets see the Cache-Context.xml file.

<?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.xsd">

      <bean name="ExampleCacheConfig" class="org.jboss.cache.config.Configuration">
      </bean>

      <!-- Factory to build the Cache. -->
      <bean name="DefaultCacheFactory"
            class="org.jboss.cache.DefaultCacheFactory"
            factory-method="getInstance" >
      </bean>

      <!-- The cache itself -->
      <bean name="ExampleCache"
                  factory-bean="DefaultCacheFactory"
                  factory-method="createCache">
                  <constructor-arg ref="ExampleCacheConfig"/>
                  <constructor-arg value="true"/>
      </bean>
     
      <!-- JMX Management -->
      <bean name="ExampleCacheJmxWrapper" class="org.jboss.cache.jmx.CacheJmxWrapper">
            <constructor-arg ref="ExampleCache"/>
      </bean>
</beans>


 Instead of drectly calling the  new DefaultCacheFactory(); one bean is initialized DefaultCacheFactory. A factory-method createCache is called on this bean which in turn initializes our ExampleCache. Now CacheJmxWrapper constructor takes an Cache type object, which is being pushed by the tag constructor-arg. Custom cache definition can be configured inside the ExampleCacheConfig bean definition. Now your cache is ready and can be accessed using spring APIs acontext.getBean("ExampleCache");
 
     
package com.ne;

import org.jboss.cache.Cache;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestCache
{

      public static void main(String[] args) throws Exception
      {
            ApplicationContext acontext = new ClassPathXmlApplicationContext("Cache-Context.xml");
            Cache cache = (Cache)acontext.getBean("ExampleCache");
           
            for(int i = 0 ; ; i++)
            {
                  String fqn = Integer.toString(i);
                  cache.put(fqn, i, i);
                  Thread.sleep(2000);
                  System.out.println("one node added : "+i);
            }
      }
}

  • JBoss Cache Statistics

JBoss Exposes various runtime statistics which can be viewed graphically through jconsole. The set of all available statistics are documented in cache userguide. A sample jconsole screenshot is attached below.



Some lifecycle operations (create/start/stop/destroy) on the cache can also be invoked through jconsole interface. Various details about the cache's current state (number of nodes, lock information, etc.) can be retrieved accordingly.