EHCACHE Replication with JMS in Spring

  • Introduction:

EHCACHE: It is widely used type of cache.

Replication: If you are using mulitple application server and you need to have same copy of cache at every application server node, then you can use EHCAHE Replication.

I am going to demostrate how EHCACHE replication achieved with Java Message Service in Spring Web Application.

We have choice of using Open MQ and Active MQ. These are open source message queues. I am using Active MQ.

  • Configuration:

A)Active MQ Setup

1. You need to download Active MQ server from this link.

http://activemq.apache.org/download.html

I have used -apache-activemq-4.1.0-incubator

2.Extract it.

3.go to follwing path-

—\apache-activemq-4.1.0-incubator\bin

run activemq.bat

ActiveMQ’s default port is 61616.

B)Spring Web App Configuration

pom.xml-


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.arceler</groupId>
<artifactId>ehcache</artifactId>
<packaging>war</packaging>
<version>1.0</version>
<name>ehcache spring annotations demo</name>
<url>http://maven.apache.org</url>
<dependencies>

<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.1</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>3.0.3.RELEASE</version>
<type>jar</type>
<scope>compile</scope>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId>
<version>3.0.3.RELEASE</version>
<type>jar</type>
<scope>compile</scope>
</dependency>

<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
<type>jar</type>
<scope>compile</scope>
</dependency>

<dependency>
<groupId>com.googlecode.ehcache-spring-annotations</groupId>
<artifactId>ehcache-spring-annotations</artifactId>
<version>1.1.2</version>
<type>jar</type>
<scope>compile</scope>
</dependency>

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.1</version>
<type>jar</type>
<scope>compile</scope>
</dependency>

<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.8.5</version>
<type>jar</type>
<scope>compile</scope>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>3.0.3.RELEASE</version>
<type>jar</type>
<scope>compile</scope>
</dependency>

<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-jmsreplication</artifactId>
<version>0.3</version>
</dependency>

<dependency>
<groupId>javax.jms</groupId>
<artifactId>javax.jms-api</artifactId>
<version>2.0-b06</version>
</dependency>
<dependency>

<groupId>org.apache.activemq</groupId>
<artifactId>activemq-core</artifactId>
<version>4.1.1</version>
</dependency>

</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
<finalName>ehcache-jms</finalName>
</build>
</project>

We have added dependancies for Spring, ehcahe and jms.

2. web.xml :

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<display-name>ehcache-jms</display-name>
<session-config>
<session-timeout>30</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/log4j.properties</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<servlet>
<description></description>
<servlet-name>springServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>

3.Spring-context.xml

–We have to create bean -cacheManager, and set configuration file location in property.

<ehcache:annotation-driven />

<ehcache:config cache-manager="cacheManager">
<ehcache:evict-expired-elements interval="60" />
</ehcache:config>

<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation" value="/WEB-INF/ehcache.xml"/>
</bean>

4. ehcache.xml- This fiile actual configuration for Ehcache

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.sf.net/ehcache.xsd">

<diskStore path="java.io.tmpdir" />

<cacheManagerPeerProviderFactory
class="net.sf.ehcache.distribution.jms.JMSCacheManagerPeerProviderFactory"
properties="initialContextFactoryName=com.arceler.ehcache.TestActiveMQInitialContextFactory,
providerURL=tcp://10.35.34.229:61616, replicationTopicConnectionFactoryBindingName=topicConnectionFactory,
replicationTopicBindingName=ehcache, getQueueConnectionFactoryBindingName=queueConnectionFactory,
getQueueBindingName=ehcacheGetQueue, topicConnectionFactoryBindingName=topicConnectionFactory,
topicBindingName=ehcache"
propertySeparator="," />
<defaultCache eternal="true" maxElementsInMemory="100"
overflowToDisk="false" />

<cache name="messageCache" maxElementsInMemory="1000" eternal="false"
timeToIdleSeconds="1000" timeToLiveSeconds="1000" overflowToDisk="false">

<cacheEventListenerFactory
class="net.sf.ehcache.distribution.jms.JMSCacheReplicatorFactory"
properties="replicateAsynchronously=true,
replicatePuts=true,
replicateUpdates=true,
replicateUpdatesViaCopy=true,
replicateRemovals=true,
asynchronousReplicationIntervalMillis=1000"
propertySeparator="," />

<cacheLoaderFactory
class="net.sf.ehcache.distribution.jms.JMSCacheLoaderFactory"
properties="initialContextFactoryName=com.arceler.ehcache.TestActiveMQInitialContextFactory,
providerURL=tcp://10.35.34.229:61616,
replicationTopicConnectionFactoryBindingName=topicConnectionFactory,
getQueueConnectionFactoryBindingName=queueConnectionFactory,
replicationTopicBindingName=ehcache,
getQueueBindingName=ehcacheGetQueue,
timeoutMillis=10000" />
</cache>

</ehcache>

5.TestActiveMQInitialContextFactory.java

We have specified

initialContextFactoryName=com.arceler.ehcache.TestActiveMQInitialContextFactory

So we have give following file.

import java.net.URISyntaxException;
import java.util.Hashtable;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.naming.Context;

import javax.naming.NamingException;

import net.sf.ehcache.distribution.jms.JMSUtil;

import org.apache.activemq.jndi.ActiveMQInitialContextFactory;

public class TestActiveMQInitialContextFactory extends ActiveMQInitialContextFactory {

/**
* Creates an initial context with
* {@inheritDoc}
*/
@Override
@SuppressWarnings("unchecked")
public Context getInitialContext(Hashtable environment) throws NamingException {

Map<String, Object> data = new ConcurrentHashMap<String, Object>();

String replicationTopicConnectionFactoryBindingName = (String)environment.get(JMSUtil.TOPIC_CONNECTION_FACTORY_BINDING_NAME);
if(replicationTopicConnectionFactoryBindingName!=null)
{
try {
data.put(replicationTopicConnectionFactoryBindingName, createConnectionFactory(environment));
} catch (URISyntaxException e) {
throw new NamingException("Error initialisating TopicConnectionFactory with message " + e.getMessage());
}
}String getQueueConnectionfactoryBindingName = (String)environment.get(JMSUtil.GET_QUEUE_CONNECTION_FACTORY_BINDING_NAME);

try {
data.put(getQueueConnectionfactoryBindingName, createConnectionFactory(environment));
} catch (URISyntaxException e) {
throw new NamingException("Error initialisating TopicConnectionFactory with message " + e.getMessage());
}

String replicationTopicBindingName = (String)environment.get(JMSUtil.REPLICATION_TOPIC_BINDING_NAME);
String getQueueBindingName = (String)environment.get(JMSUtil.GET_QUEUE_BINDING_NAME);
if(replicationTopicBindingName!=null)
{
data.put(replicationTopicBindingName, createTopic(replicationTopicBindingName));
}
data.put(getQueueBindingName, createQueue(getQueueBindingName));
return createContext(environment, data);
}
}
Advertisements

7 responses to “EHCACHE Replication with JMS in Spring

  1. You created some good stuff in ur blog, “EHCACHE Replication with JMS in Spring | Pravinchavan’s Blog”. I’ll become coming back again to
    your web site before long. Thanks a lot -Penni

  2. Hello! Someone in my Facebook group shared this site with us so I came to
    give it a look. I’m definitely loving the information. I’m book-marking and
    will be tweeting this to my followers! Fantastic blog and wonderful style and design.

  3. Woah! I’m really digging the template/theme of this site. It’s simple,
    yet effective. A lot of times it’s very hard to get that “perfect balance” between user friendliness and visual appeal. I must say you’ve done a amazing job
    with this. Additionally, the blog loads extremely fast
    for me on Opera. Outstanding Blog!

Leave a Reply

Fill in your details below or click an icon to log in:

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