Introduction, Using, Developing Web applications and Java Object Caching with Java Caching System (JCS)

The article is written for/using J2SE 6, Java Caching System (JCS) 1.3.2.8, and Eclipse IDE for Java EE Developers [Galileo].

Table of Content

  1. Introduction
  2. System Requirements
  3. Article Prerequisites
  4. Caching Overview
  5. Caching Frameworks
  6. JCS Overview
  7. JCS Regions
  8. JCS Cache Regions Configuration
  9. Setup Eclipse, JCS
  10. Develop JCS Cache Demo
  11. Summary
  12. Resources
  13. Feedback

Introduction

This article explains Java Caching System (JCS) and how to use JCS. The usage of JCS is demonstrated for stand-alone Java applications but same can be implemented inside the Java EE environment.

Back to the top

System Requirements

The list of dependencies for Java Caching System (JCS) can be found here. To follow along and try out the code for this tutorial, you need a working installation of either:

The instructions and examples in the tutorial are based on a Microsoft® Windows® operating system. All the tools covered in the tutorial also work on Linux® and UNIX® systems.

Back to the top

Article Prerequisites

To get the most from this tutorial, you should be familiar with Java syntax and the basic concepts of object-oriented development on the Java platform.

Back to the top

Caching Overview

A cache, is a collection of objects. A cache is designed to hold objects, typically in memory, for immediate access by an application. An application interacts differently with a cache from the way it interacts with external storage solutions. Caching and Pooling are whole different thing. The objects in a cache have state where as objects in a pool do not have state. Pools may grow and shrink to meet demand, but when a cache shrinks, it is not a simple matter of randomly removing an item from the cache because a running process might need access to that object. Therefore a cache needs to be sized appropriately enough to satisfy the application it serves; large enough that most requests are serviced by the cache, but not too large as to consume too many resources. Which objects should be cached and what objects should be pooled? If an object maintains state, it should be cached. Stateless objects should be pooled.

Caching of frequently viewed data that changes infrequently is a powerful way to decrease wait time for users. Caches may also provide redundancy. If your caching solution is serving as a performance enhancement that sits in front of your database then you want to ensure that it is highly available. Therefore, caches usually support some sort of replication strategy to persist redundant copies of the data on additional servers.

Back to the top

Caching Frameworks

  • Apache Java Caching System (JCS)
  • JCS is a distributed caching system written in java. Can be used to create Java desktop and Web applications. It provides mechanisms for storing data in the cache, getting data from the cache, removing data from the cache, in-memory caching, indexed disk caching, distributed caches and much more.

  • Ehcache
  • Ehcache is a java distributed cache for general purpose caching, J2EE and light-weight containers tuned for large size cache objects. It features memory and disk stores, replicate by copy and invalidate, listeners, a gzip caching servlet filter and much more.

  • OSCache
  • OSCache is a caching solution that includes a JSP tag library and set of classes to perform fine grained dynamic caching of JSP content, servlet responses or arbitrary objects. It provides both in memory and persistent on disk caches, and much more.

  • SwarmCache
  • Cache4J
  • Cache4j is a cache for Java objects that stores objects only in memory. It is mainly useful for caching POJO objects only.

  • JBossCache
  • Oracle Coherence
  • WhirlyCache

Back to the top

JCS Overview

JCS is a open source distributed caching system written in java. Can be used to create Java desktop and Web applications. It provides mechanisms for storing data in the cache, getting data from the cache, removing data from the cache, in-memory caching, indexed disk caching, distributed caches and much more. A JCS cache has a map-like structure in which data is stored in the cache as a name-and-value pair. The keys in one region can be the same as keys in other regions.

Back to the top

JCS Regions

In JCS, you can store cached data in different data regions. JCS defines four types of core regions: memory, disk, lateral, and remote. You can also specify which region should be used first and when to fail over to another region. Each region can define cache attributes as well as element attributes. A cache attribute defines a configuration option for the cache, whereas an element attribute defines a configuration option for the elements in the cache.

  • Memory region – Least Recently Used (LRU)
  • This is a pure-memory cache region that uses a Least Recently Used (LRU) algorithm. An extremely fast, highly configurable memory cache.

  • Disk region
  • Fast, reliable and highly configurable swap for cached data. To improve performance, JCS stores the cached data keys in memory while storing the actual cached data on the file disk.

  • Remote region – Remote Method Invocation (RMI)
  • A remote cache server can be configured as a central connection point for all the nodes instead of each maintaining a connection with the every other node. This cache region provides chaching using a Remote Method Invocation (RMI) API.

  • Lateral region – TCP/UDP
  • Provides an easy way to distribute cache data into multiple servers. The cached data servers must have a port open to listen on, and a socket connection must be created.

Back to the top

JCS Cache Regions Configuration

The default region defines the default configuration for all regions unless it is overridden explicitly by one of the other regions. Then there are user-defined regions comes. Auxiliary caches define auxiliaries that can be plugged into a cache region. Configuring JCS is creating and populating a cache.ccf file. This file defines which regions your cache should use and the attributes or options of those regions. The very basic JCS pure memory configuration could be:

# DEFAULT CACHE REGION
jcs.default=
jcs.default.cacheattributes=org.apache.jcs.engine.CompositeCacheAttributes
jcs.default.cacheattributes.MaxObjects=1000
jcs.default.cacheattributes.MemoryCacheName=org.apache.jcs.engine.memory.lru.LRUMemoryCache

You can have more comprehensive configuration. Below exmaple shows JCS configuration using memory region and disk region:

# DEFAULT CACHE REGION. A pure memory cache.
jcs.default=BASE_REGION
jcs.default.cacheattributes=org.apache.jcs.engine.CompositeCacheAttributes
jcs.default.cacheattributes.MaxObjects=1000
jcs.default.cacheattributes.MemoryCacheName=org.apache.jcs.engine.memory.lru.LRUMemoryCache
jcs.default.cacheattributes.UseMemoryShrinker=true
jcs.default.cacheattributes.MaxMemoryIdleTimeSeconds=3600
jcs.default.cacheattributes.ShrinkerIntervalSeconds=60
jcs.default.elementattributes=org.apache.jcs.engine.ElementAttributes
jcs.default.elementattributes.IsEternal=false
jcs.default.elementattributes.MaxLifeSeconds=21600
jcs.default.elementattributes.IdleTime=1800
jcs.default.elementattributes.IsSpool=true
jcs.default.elementattributes.IsRemote=true
jcs.default.elementattributes.IsLateral=true

# PREDEFINED CACHE REGIONS.
jcs.region.DEMO_REGION=BASE_REGION
jcs.region.DEMO_REGION.cacheattributes=org.apache.jcs.engine.CompositeCacheAttributes
jcs.region.DEMO_REGION.cacheattributes.MaxObjects=1000
jcs.region.DEMO_REGION.cacheattributes.MemoryCacheName=org.apache.jcs.engine.memory.lru.LRUMemoryCache
jcs.region.DEMO_REGION.cacheattributes.UseMemoryShrinker=true
jcs.region.DEMO_REGION.cacheattributes.MaxMemoryIdleTimeSeconds=3600
jcs.region.DEMO_REGION.cacheattributes.ShrinkerIntervalSeconds=60
jcs.region.DEMO_REGION.cacheattributes.MaxSpoolPerRun=500
jcs.region.DEMO_REGION.elementattributes=org.apache.jcs.engine.ElementAttributes
jcs.region.DEMO_REGION.elementattributes.IsEternal=false

# AVAILABLE AUXILIARY CACHES.
jcs.auxiliary.BASE_REGION=org.apache.jcs.auxiliary.disk.indexed.IndexedDiskCacheFactory
jcs.auxiliary.BASE_REGION.attributes=org.apache.jcs.auxiliary.disk.indexed.IndexedDiskCacheAttributes
jcs.auxiliary.BASE_REGION.attributes.DiskPath=c:/temp
jcs.auxiliary.BASE_REGION.attributes.MaxPurgatorySize=10000000
jcs.auxiliary.BASE_REGION.attributes.MaxKeySize=1000000
jcs.auxiliary.BASE_REGION.attributes.MaxRecycleBinSize=5000
jcs.auxiliary.BASE_REGION.attributes.OptimizeAtRemoveCount=300000
jcs.auxiliary.BASE_REGION.attributes.ShutdownSpoolTimeLimit=60

Here is a summary of the cache attribute options:

  • MaxObjects
  • Defines the maximum number of objects allowed in memory.

  • MemoryCacheName
  • Allows you to define the memory manager to use as your MemoryCache. The default memory manager implements a LRU strategy.

  • UseMemoryShrinker
  • Allows JCS to iterate periodically over the cache, looking for objects that can be removed. Default is false.

  • MaxMemoryIdleTimeSeconds
  • If the memory shrinker is enabled, this property tells JCS how long an object can remain idle before the shrinker removes it. Default is -1.

  • ShrinkerIntervalSeconds
  • If the memory shrinker is enabled, this property tells JCS how often to run the shrinker. Default is 60 seconds.

  • DiskUsagePattern
  • If a disk cache is enabled, this property tells JCS how to persist data when the memory cache is full. Default is SWAP. The other option is UPDATE, which persists all data out to disk, but only when data is updated.

Here is a summary of the element attribute options:

  • IsEternal
  • If an element is eternal then it cannot be removed from the cache because it exceeds its maximum life. Default is true.

  • MaxLifeSeconds
  • If elements are not eternal, this option defines the maximum life of each object before it is removed. Default is -1.

  • IsSpool
  • Defines whether or not an element can be spooled out to disk. Default is true.

  • IsLateral
  • Defines whether or not an element can be sent to a lateral cache. Default is true.

  • IsRemote
  • Defines whether or not an element can be sent to a remote cache. Default is true.

Back to the top

Setup Eclipse, JCS

Let’s setup Eclipse and JCS. Extract eclipse-jee-galileo-SR2-win32.zip into your drive. Extract JCS, commons-logging, concurrent zip to a diretory, lets call it JCSJars. Your JCSJars directory should contain i) jcs-1.3.jar ii) commons-logging-1.1.1.jar iii) concurrent-1.3.4.jar

Now you need to setup User Library for Java Caching System 1.3 in Eclipse. In Eclipse, select Window -> Preferences -> Java -> Build Path -> User Libraries. Click Configure User Libraries…. Click New… and give name Java Caching System 1.3 and press OK. Click Add JARs…. Browse location where you have extracted JCS, commons-logging, concurrent jars and select all JARs. Now right click on project and goto Properties -> Libraries -> Add Library… -> User Library -> Next > and select Java Caching System 1.3. Press Finish. Press OK.

Back to the top

Develop JCS Cache Demo

To get started we will create a simple Java Project by selecting New > Project… > Java Project > Next from the File menu.

Name the project JCSCacheDemo. Click Next >. Click on Libraries tab and click Add Library…. Select User Library and click Next >. Check Java Caching System 1.3 and click Finish.

First, lets create cache.ccf file. Goto JCSCacheDemo > src and right click. From the pop up menu, select New > Other… > General > File. The New File dialog box will appear. Provide parent folder as JCSCacheDemo/src and give file name cache.ccf. Copy the JCS configuration from above example which shows the JCS configuration using memory region and disk region.

The cache can be initialized either automatically or manually. If you name your configuration file cache.ccf and put it directly in your CLASSPATH (such as your root build directory), then the first time JCS is invoked it finds the file and initializes appropriately. If you need to store your configuration file elsewhere or name it differently, you can use the org.apache.jcs.utils.props.PropertyLoader’s loadProperties() method to load JCS properties from any properties file.

Now let’s create the JCS Generic Cache Manager which can utilized with to store collection of any Java objects. To start with, right click on JCSCacheDemo > src and select New > Class. The New Java Class dialog box will appear. Give package name as edu.bhavesh.jcs.cache.manager and class name as JCSGenericCacheManager. Click Finish.

Replace the contents of the generated class with the following code:

package edu.bhavesh.jcs.cache.manager;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;

import org.apache.jcs.JCS;
import org.apache.jcs.access.exception.CacheException;
import org.apache.jcs.admin.CacheElementInfo;
import org.apache.jcs.admin.CacheRegionInfo;
import org.apache.jcs.admin.JCSAdminBean;
import org.apache.jcs.engine.control.CompositeCache;

/**
 * Generic JCS Cache Manager which can hold any collection of Java Objects.
 *
 * @author Bhavesh Thaker
 */
public class JCSGenericCacheManager<T> {

	/**
	 * JCS object.
	 */
	private static JCS CACHE = null;
	/**
	 * JCS region name - default.
	 */
	private static String CACHE_REGION_NAME = "default";
	/**
	 * Map holding multiple caches for each kind of Java Objects.
	 */
	private static Map<Class<?>, Object> instanceMap = new HashMap<Class<?>, Object>();

	static {
		try {
			JCSGenericCacheManager.CACHE = JCS
					.getInstance(JCSGenericCacheManager.CACHE_REGION_NAME);
		} catch (final CacheException e) {
			e.printStackTrace();
		} catch (final Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Returns the JCS Cache Manager's instance.
	 */
	@SuppressWarnings("unchecked")
	public static <T> JCSGenericCacheManager<T> getInstance(
			final Class<T> classObject) throws Exception {
		T instance = (T) JCSGenericCacheManager.instanceMap.get(classObject);
		if (instance != null) {
			return (JCSGenericCacheManager<T>) instance;
		}

		try {
			synchronized (JCSGenericCacheManager.class) {
				instance = (T) new JCSGenericCacheManager<T>();
				JCSGenericCacheManager.instanceMap.put(classObject, instance);
			}
		} catch (final ClassCastException classCastException) {
			throw new IllegalArgumentException(classCastException);
		}

		return (JCSGenericCacheManager<T>) instance;
	}

	/**
	 * Private constructor.
	 */
	private JCSGenericCacheManager() throws Exception {
		if (JCSGenericCacheManager.CACHE == null) {
			throw new Exception("JCS Cache not initialized");
		}
	}

	/**
	 * Clear JCS Cache.
	 */
	public void clearCache() {
		try {
			JCSGenericCacheManager.CACHE.clear();
		} catch (final CacheException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Dispose JCS Cache.
	 */
	public void disposeCache() {
		JCSGenericCacheManager.CACHE.dispose();
	}

	/**
	 * Gets the JCS Cached items meta data.
	 */
	@SuppressWarnings("unchecked")
	public CacheElementInfo[] getCachedItemsMetadata() throws Exception {
		CacheElementInfo[] cacheElementInfoArray = null;
		int i = 0;

		final JCSAdminBean jcsAdminBean = new JCSAdminBean();
		final LinkedList<CacheElementInfo> cacheElementInfoLinkedList = jcsAdminBean
				.buildElementInfo(JCSGenericCacheManager.CACHE_REGION_NAME);

		cacheElementInfoArray = new CacheElementInfo[cacheElementInfoLinkedList
				.size()];

		for (final CacheElementInfo cacheElementInfo : cacheElementInfoLinkedList) {
			cacheElementInfoArray[i] = cacheElementInfo;
			i++;
		}
		return cacheElementInfoArray;
	}

	/**
	 * Gets the JCS Cache Regions meta data.
	 */
	@SuppressWarnings("unchecked")
	public CompositeCache[] getCacheRegionsMetadata() throws Exception {
		CompositeCache[] compositeCacheArray = null;
		int i = 0;

		final JCSAdminBean jcsAdminBean = new JCSAdminBean();
		final LinkedList<CacheRegionInfo> cacheRegionInfoLinkedList = jcsAdminBean
				.buildCacheInfo();

		compositeCacheArray = new CompositeCache[cacheRegionInfoLinkedList
				.size()];

		for (final CacheRegionInfo cacheRegionInfo : cacheRegionInfoLinkedList) {
			final CompositeCache compositeCache = cacheRegionInfo.getCache();
			compositeCacheArray[i] = compositeCache;
			i++;
		}

		return compositeCacheArray;
	}

	/**
	 * Get item from JCS Cache.
	 */
	@SuppressWarnings("unchecked")
	public T getItem(final String item) throws Exception {
		if (JCSGenericCacheManager.CACHE == null) {
			throw new Exception("JCS Cache not initialized");
		}
		final T t = (T) JCSGenericCacheManager.CACHE.get(item);
		return t;
	}

	/**
	 * Put item in JCS Cache.
	 */
	public boolean putItem(final String item, final T tObject) throws Exception {
		try {
			JCSGenericCacheManager.CACHE.put(item, tObject);
			return true;
		} catch (final Exception e) {
			e.printStackTrace();
			throw e;
		}
	}

	/**
	 * Removes item from JCS Cache.
	 */
	public void removeItem(final String item) throws Exception {
		JCSGenericCacheManager.CACHE.remove(item);
	}
}

Now let’s create the value object class which will get stored as objects in JCS Cache. Again, right click on JCSCacheDemo > src and select New > Class. The New Java Class dialog box will appear. Give package name as edu.bhavesh.jcs.cache.vo and class name as StudentVO. Click Finish.

Replace the contents of the generated class with the following code:

package edu.bhavesh.jcs.cache.vo;

/**
 * @author Bhavesh Thaker
 */
public class StudentVO implements java.io.Serializable {

	private static final long serialVersionUID = 1L;

	private int id;
	private String studentName;
	private int studentAge;
	private String studentAddress;
	private int studentYear;

	/**
     * Constructor.
     */
	public StudentVO(final int id, final String studentName,
			final int studentAge, final String studentAddress,
			final int studentYear) {
		this.id = id;
		this.studentName = studentName;
		this.studentAge = studentAge;
		this.studentAddress = studentAddress;
		this.studentYear = studentYear;
	}

	/**
	 * @return the id
	 */
	public int getId() {
		return this.id;
	}

	/**
	 * @return the studentAddress
	 */
	public String getStudentAddress() {
		return this.studentAddress;
	}

	/**
	 * @return the studentAge
	 */
	public int getStudentAge() {
		return this.studentAge;
	}

	/**
	 * @return the studentName
	 */
	public String getStudentName() {
		return this.studentName;
	}

	/**
	 * @return the studentYear
	 */
	public int getStudentYear() {
		return this.studentYear;
	}

	/**
	 * @param id
	 *            the id to set
	 */
	public void setId(final int id) {
		this.id = id;
	}

	/**
	 * @param studentAddress
	 *            the studentAddress to set
	 */
	public void setStudentAddress(final String studentAddress) {
		this.studentAddress = studentAddress;
	}

	/**
	 * @param studentAge
	 *            the studentAge to set
	 */
	public void setStudentAge(final int studentAge) {
		this.studentAge = studentAge;
	}

	/**
	 * @param studentName
	 *            the studentName to set
	 */
	public void setStudentName(final String studentName) {
		this.studentName = studentName;
	}

	/**
	 * @param studentYear
	 *            the studentYear to set
	 */
	public void setStudentYear(final int studentYear) {
		this.studentYear = studentYear;
	}

}

Now let’s create the main class to test the power and features of JCS Cache. Again, right click on JCSCacheDemo > src and select New > Class. The New Java Class dialog box will appear. Give package name as edu.bhavesh.jcs.cache and class name as JCSCachingDemo. Click Finish.

Replace the contents of the generated class with the following code:

package edu.bhavesh.jcs.cache;

import org.apache.jcs.admin.CacheElementInfo;
import org.apache.jcs.engine.control.CompositeCache;

import edu.bhavesh.jcs.cache.manager.JCSGenericCacheManager;
import edu.bhavesh.jcs.cache.vo.StudentVO;

/**
 * Main class to test JCS Cache.
 *
 * @author Bhavesh Thaker
 */
public class JCSCachingDemo {

	/**
	 * Main method.
	 */
	public static void main(final String[] args) {
		new JCSCachingDemo();
	}

	/**
	 * Cache Manager.
	 */
	public JCSGenericCacheManager<StudentVO> jcsGenericCacheManager = null;

	/**
	 * Default constructor.
	 */
	public JCSCachingDemo() {
		try {
			this.jcsGenericCacheManager = JCSGenericCacheManager
					.getInstance(StudentVO.class);
		} catch (final Exception e) {
			e.printStackTrace();
		}

		this.loadCacheForDemo();
		this.showCacheRegionsMetadata();
		this.showCachedItemsMetadata();

		try {
			System.out.println("===== GET CALLED =====");
			StudentVO studentVO1 = this.jcsGenericCacheManager.getItem("" + 1);
			System.out.println("ID: " + studentVO1.getId() + "\tName: "
					+ studentVO1.getStudentName() + "\tAge: "
					+ studentVO1.getStudentAge() + "\tYear: "
					+ studentVO1.getStudentYear() + "\tAddress: "
					+ studentVO1.getStudentAddress());
			StudentVO studentVO2 = this.jcsGenericCacheManager.getItem("" + 3);
			System.out.println("ID: " + studentVO2.getId() + "\tName: "
					+ studentVO2.getStudentName() + "\tAge: "
					+ studentVO2.getStudentAge() + "\tYear: "
					+ studentVO2.getStudentYear() + "\tAddress: "
					+ studentVO2.getStudentAddress());

			this.showCacheRegionsMetadata();
			this.showCachedItemsMetadata();

			System.out.println("===== REMOVE CALLED =====");
			this.jcsGenericCacheManager.removeItem("" + 3);
			this.showCacheRegionsMetadata();
			this.showCachedItemsMetadata();

			System.out.println("===== CLEAR CALLED =====");
			this.jcsGenericCacheManager.clearCache();
			this.showCacheRegionsMetadata();
			this.showCachedItemsMetadata();

			System.out.println("===== DISPOSE CALLED =====");
			this.jcsGenericCacheManager.disposeCache();
			this.showCacheRegionsMetadata();
			this.showCachedItemsMetadata();
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	/**
	 * Loading the JCS Cache.
	 */
	private void loadCacheForDemo() {
		if (this.jcsGenericCacheManager != null) {
			final StudentVO studentVO_1 = new StudentVO(1, "Bhavesh Thaker",
					30, "India", 2010);
			final StudentVO studentVO_2 = new StudentVO(2, "Rational Java", 25,
					"USA", 2011);
			final StudentVO studentVO_3 = new StudentVO(3, "Blogspot", 22,
					"UK", 2009);
			final StudentVO studentVO_4 = new StudentVO(4, "JCS Cache", 28,
					"India", 2008);

			try {
				this.jcsGenericCacheManager.putItem("" + studentVO_1.getId(),
						studentVO_1);
				this.jcsGenericCacheManager.putItem("" + studentVO_2.getId(),
						studentVO_2);
				this.jcsGenericCacheManager.putItem("" + studentVO_3.getId(),
						studentVO_3);
				this.jcsGenericCacheManager.putItem("" + studentVO_4.getId(),
						studentVO_4);
			} catch (final Exception e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * Getting the Cached Items Meta-Data.
	 */
	private void showCachedItemsMetadata() {
		try {
			final CacheElementInfo[] cacheElementInfoArray = this.jcsGenericCacheManager
					.getCachedItemsMetadata();
			for (final CacheElementInfo element : cacheElementInfoArray) {
				System.out.println("Key: " + element.getKey());
				System.out.println("Creation Time: " + element.getCreateTime());
				System.out.println("Maximum Life (seconds): "
						+ element.getMaxLifeSeconds());
				System.out.println("Expires in (seconds): "
						+ element.getExpiresInSeconds());
			}
		} catch (final Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Getting the Cached Region Meta-Data.
	 */
	private void showCacheRegionsMetadata() {
		try {
			final CompositeCache[] compositeCacheArray = this.jcsGenericCacheManager
					.getCacheRegionsMetadata();
			for (final CompositeCache element : compositeCacheArray) {
				System.out.println("Cache Name: " + element.getCacheName());
				System.out.println("Cache Type: " + element.getCacheType());
				System.out.println("Cache Misses (not found): "
						+ element.getMissCountNotFound());
				System.out.println("Cache Misses (expired): "
						+ element.getMissCountExpired());
				System.out.println("Cache Hits (memory): "
						+ element.getHitCountRam());
				System.out
						.println("Cache Updates: " + element.getUpdateCount());
			}

		} catch (final Exception e) {
			e.printStackTrace();
		}
	}

}

Back to the top

Summary

JCS is a powerful caching system. It provides data caching for desktop and Web applications. This article has shown how to configure and use JCS.

The primary benefit of a cache is that objects can be served from local memory faster than they can be loaded from an external data source, such as a database located across a network. The drawback is that caches can consume a considerable amount of memory, and if objects and their usage patterns are not analyzed thoroughly, cache management can introduce another bottleneck into your application.

In this article/tutorial, we learned the Java Caching System (JCS) and how to use it in Java SE desktop applications that require object caching. Same can be implemented for web applications as well.

Back to the top

Downloads

Downloads

JCSCacheDemo.zip contains the JCSCacheDemo project we created in this tutorial.

Back to the top

Resources

Back to the top

Feedback

I would like to hear from you! If you liked this tutorial, have some suggestions or even some corrections for me, please let me know. I track all user feedback in comments sections.

Back to the top

3 Comments

  1. Vasu Dev K V says:

    I tried but i am getting the files in C:temp folder as 0kb i.e.. empty files, can u help me y it is so…

    one more thing is i want to use two main methods, when i execute first main method i want to store the data in the cache and when i execute second main method i want to retrieve from the cache.

    Can u post an example for this, actually i am searching this for a long time but not able to achiev…

  2. Shakun says:

    Which auxiliary type I need to use for cache replication in fail over.

  3. Abhijit Mondal says:

    Can you plz help me to configure for JCS disk region or give a simple project done on it. I need that too much.

Leave a Reply

Your email address will not be published. Required fields are marked *