Spring, EHCache, Maven Integration

Here’s a quick Maven project with the absolute minimal for a “hello world” EHCache example.

EHCache exists as a dependency in the central Maven repo so no need to add additional repo information. Also this is a special dependency that requires dependency.type to be specified as pom. Finally the only dependency is on SLF4J for logging purposes so I’ve added LOGBack. The POM looks like this:

<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/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.dimitrisli</groupId>
  <artifactId>ehcacheFirstExample</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <properties>
  	<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
  <dependencies>
    <dependency>
      <groupId>net.sf.ehcache</groupId>
      <artifactId>ehcache</artifactId>
      <version>2.5.0</version>
      <type>pom</type>
      <scope>compile</scope>
    </dependency>
    <dependency>
    	<groupId>ch.qos.logback</groupId>
    	<artifactId>logback-classic</artifactId>
    	<version>1.0.0</version>
    </dependency>
  </dependencies>
</project>

The EHCache configuration file served in xml flavor has the default name ehcache.xml and looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
	<cache name="sampleCacheFromEhcacheXml"
	    maxElementsInMemory="500"
	    eternal="false"
	    timeToIdleSeconds="300"
	    timeToLiveSeconds="300"
	    overflowToDisk="false">
	 </cache>
</ehcache>

Some things to notice:

  • The generic ehcache tag includes the cache tag with all its parameters as attributes.
  • maxElementsInMemory: this is the max number of elements that the cache can hold.
  • timeToIdleSeconds: this is the number of seconds elements can live in the cache without being requested.
  • timeToLiveSeconds: this is the number of seconds elements can reside inside the cache.
  • eternal: this is overriding both the two previous parameters if set to true and it does what it says in the box, it keeps the elements for the length the cache lives into the memory.
  • A nice alternative is the parameter overflowToOffHeap which if set to true then the cache is stored outside of the Heap! This way the cache is not entitled to Garbage Collection slow downs and the performance can be increased as advertised in the EHCache website. Unfortunately all this power comes with a cost, namely to activate the off-heap storage a licence key is needed after a 30 days trial. Here’s a speed/size/memory diagram:


Finally the test class looks like this:

package com.dimitrisli.ehcache;

import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;

public class EHCacheFirstExample {

	private final CacheManager cacheManager;
	private final Cache cache;

	public EHCacheFirstExample(){
		//cacheManager = new CacheManager(getClass().getResource("/src/main/resources/ehcache.xml"));
		cacheManager = CacheManager.create();
		cache = cacheManager.getCache("sampleCacheFromEhcacheXml");
	}

	public Cache getCache() {
		return this.cache;
	}

	public void addElementToCache(Element element){
		this.cache.put(element);
	}

	public static void main(String[] args) {
		EHCacheFirstExample fe = new EHCacheFirstExample();
		fe.addElementToCache(new Element("myCacheEntryKey","myCacheEntryVal"));
		for(Object key : fe.getCache().getKeys()){
			System.out.println(key + ":"+ (String) fe.getCache().get(key).getObjectValue());
		}
	}
}

A couple of things to notice: the CacheManagercan be created either as a singleton through its static factory method

CacheManager.create()

or a new instance specifying as a URL the location of the EHCache property file. Moreover the “convention over configuration” mantra of Maven makes

src/main/resources

the ideal place for the ehcache.xml properties file to live. Finally the Cache object as well as the Element object are not generic objects therefore making the iteration a bit cumbersome and the runtime-checking/casting feeling so 1.4

You can find the code in this github repository