In Part 5 of this series, we mentioned that Ehcache could be configured at runtime via ColdFusion code as well as by using an XML configuration file called ehcache.xml.
On a Java EE install of ColdFusion 9, you can find the ehcache.xml file located here:
/JRun4/servers/servername/cfusion-ear/cfusion-war/WEB-INF/cfusion/lib
There are two main sections of the file you need to be concerned with for basic configuration. The first section you should take a look at is the DiskStore configuration:
ColdFISH is developed by Jason Delmore. Source code and license information available at coldfish.riaforge.org
<diskStore path="java.io.tmpdir"/>
1<diskStore path="java.io.tmpdir"/>
This tag tells Ehcache where it should write cache files if you have the cache configured to overflow to disk or to persist to disk. We'll get into the specifics of those options, but for now it's important to know that by default Ehcache will use your Java temp directory to store cache files if it is configured to do so. On Windows, the Java temp directory is located in c:/windows/temp. You can change the value here to any drive/directory on your system if you wish to use a location other than the Java temp directory.
The next section to take a look at comes at the end of the ehcache.xml file. Skip on down to the very end where you should see a block of XML that looks like this:
ColdFISH is developed by Jason Delmore. Source code and license information available at coldfish.riaforge.org
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="86400"
timeToLiveSeconds="86400"
overflowToDisk="false"
diskSpoolBufferSizeMB="30"
maxElementsOnDisk="10000000"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="3600"
memoryStoreEvictionPolicy="LRU"
/>
1<defaultCache
2 maxElementsInMemory="10000"
3 eternal="false"
4 timeToIdleSeconds="86400"
5 timeToLiveSeconds="86400"
6 overflowToDisk="false"
7 diskSpoolBufferSizeMB="30"
8 maxElementsOnDisk="10000000"
9 diskPersistent="false"
10 diskExpiryThreadIntervalSeconds="3600"
11 memoryStoreEvictionPolicy="LRU"
12 />
This block of XML tells ColdFusion how to configure all of the Object and Template caches that are automatically created for your application. When a cache is automatically created, the name for the cache is also automatically created using the convention appnameOBJECT for object caches and appnameTEMPLATE for template caches. Each cache has a number configurable parameters:
- maxElementsInMemory: Sets the max number of objects that will be created in memory. Once this limit is reached, the cache will either overflow to disk (if overflowToDisk is set to true), or the appropriate eviction policy will be executed against the cache to make enough room for the new item(s) being added.
- eternal: Sets whether elements are eternal. If eternal is set to true, timeouts are ignored and the element is never expired.
- timeToIdleSeconds: Sets the time to idle for an element before it expires.
- timeToLiveSeconds: Sets the time to live for an element before it expires.
- overflowToDisk: Sets whether elements can overflow to disk when the memory store has reached the maxElementsInMemory limit.
- diskSpoolBufferSizeMB: Specifies the spool buffer size for the DiskStore, if enabled. Writes are made to the spool buffer before they are asynchronously written to the DiskStore.
- maxElementsOnDisk: Sets the max number of objects that will be maintained in the DiskStore
- diskPersistent: Whether the disk store persists between restarts of the Virtual Machine.
- diskExpiryThreadIntervalSeconds: Specifies the interval (in seconds) between runs of the disk expiry thread.
- memoryEvictionPolicy: Policy to enforce upon reaching the maxElementsInMemory limit (LRU, LFU, FIFO).
If you make changes to any of these parameters, ColdFusion will apply them to any new caches that it automatically creates. If you have disk persistence or overflow to disk turned on, two files will be written to your file system per cache, an index file and a data file. For an object cache you would get appnameOBJECT.index and appnameOBJECT.data.
If you want to see what properties have been set for your application's cache, you can do so using the cacheGetProperties() function. The function takes a single optional parameter that specifies the type of cache to return the properties for. Options are Template or Object. If you don't specify the cache type to return properties for, ColdFusion returns them for both cache types. Here's an example that dumps the properties for both the default Object and Template caches:
ColdFISH is developed by Jason Delmore. Source code and license information available at coldfish.riaforge.org
<cfdump var="#cacheGetProperties()#">
1<cfdump var="#cacheGetProperties()#">
This will result in output that looks like this:

As you can see from the screen shot, the structure keys correlate to parameters form the ehcache.xml file with two notable exceptions. Both diskSpoolBufferSizeMB and diskExpiryThreadIntervalSeconds are not reported on as properties that can be changed programmatically at runtime.
If you wish to change any of these properties programmatically, you can do so using the cacheSetProperties() function. This function takes a single argument – a structure containing all of the properties that should be configured. You can configure any of the following parameters:
- objectType: Specifies the cache type: Object, Template, or All
- diskStore: Supposed to specify the location of the DiskStore for disk based caching but this is currently not working as of ColdFusion 9.0.
- diskPersistent: Whether the disk store persists between restarts of the Virtual Machine. True|False
- eternal: Sets whether elements are eternal. If eternal, timeouts are ignored and the element is never expired. True|False
- maxElementsInMemory: Sets the max number of objects that will be created in memory. Integer
- maxElementsOnDisk: Sets the max number of objects that will be maintained in the DiskStore. Integer
- memoryEvictionPolicy: Policy to enforce upon reaching the maxElementsInMemory limit: LRU, LFU, FIFO
- overflowToDisk: Sets whether elements can overflow to disk when the memory store has reached the maxElementsInMemory limit: True|False
- timeToIdleSeconds: Sets the time to idle for an element before it expires: Integer number of seconds
- timeToLiveSeconds: Sets the time to live for an element before it expires: Integer number of seconds
Remember, this only applies to caches automatically created by ColdFusion. If a cache doesn't yet exist and you call cacheSetProperties(), ColdFusion will automatically create the cache for you based on whether you are setting properties for an Object cache, a Template cache, or both.
The following code shows how to build the structure of parameters necessary to configure a cache and set the cache properties using the cacheSetProperties() function:
ColdFISH is developed by Jason Delmore. Source code and license information available at coldfish.riaforge.org
<cfset myProps = structNew()>
<!---
<cfset myProps.diskstore = "c:/temp"> <!--- in the docs, but not currently implemented --->
--->
<cfset myProps.diskpersistent = "true">
<cfset myProps.eternal = "false">
<cfset myProps.maxelementsinmemory = "5000">
<cfset myProps.maxelementsondisk = "100000">
<cfset myProps.memoryevictionpolicy = "LRU">
<cfset myProps.objecttype = "Object">
<cfset myProps.overflowtodisk = "true">
<cfset myProps.timetoidoleconds = "86400">
<cfset myProps.timetolivesecond = "86400">
Before:
<cfdump var="#cacheGetProperties("Object")#">
<!--- update the cache properties --->
<cfset cacheSetProperties(myProps)>
After:
<cfdump var="#cacheGetProperties("Object")#">
1<cfset myProps = structNew()>
2<!---
3<cfset myProps.diskstore = "c:/temp"> <!--- in the docs, but not currently implemented --->
4--->
5<cfset myProps.diskpersistent = "true">
6<cfset myProps.eternal = "false">
7<cfset myProps.maxelementsinmemory = "5000">
8<cfset myProps.maxelementsondisk = "100000">
9<cfset myProps.memoryevictionpolicy = "LRU">
10<cfset myProps.objecttype = "Object">
11<cfset myProps.overflowtodisk = "true">
12<cfset myProps.timetoidoleconds = "86400">
13<cfset myProps.timetolivesecond = "86400">
14
15Before:
16<cfdump var="#cacheGetProperties("Object")#">
17
18<!--- update the cache properties --->
19<cfset cacheSetProperties(myProps)>
20
21After:
22<cfdump var="#cacheGetProperties("Object")#">
It's also possible to create more caches than just the default template and object caches that ColdFusion creates automatically for you. This can be achieved by defining them in your ehcache.xml file or at runtime using the cfcache tag. To configure a new cache region in your ehcache.xml file, you would do so like this (place this before or after the defaultCache block in your ehcache.xml file):
ColdFISH is developed by Jason Delmore. Source code and license information available at coldfish.riaforge.org
<cache
name="myCustomObjectCache"
maxElementsInMemory="500"
eternal="false"
timeToIdleSeconds="86400"
timeToLiveSeconds="86400"
overflowToDisk="true"
diskSpoolBufferSizeMB="30"
maxElementsOnDisk="10000000"
diskPersistent="true"
diskExpiryThreadIntervalSeconds="3600"
memoryStoreEvictionPolicy="LRU">
1<cache
2 name="myCustomObjectCache"
3 maxElementsInMemory="500"
4 eternal="false"
5 timeToIdleSeconds="86400"
6 timeToLiveSeconds="86400"
7 overflowToDisk="true"
8 diskSpoolBufferSizeMB="30"
9 maxElementsOnDisk="10000000"
10 diskPersistent="true"
11 diskExpiryThreadIntervalSeconds="3600"
12 memoryStoreEvictionPolicy="LRU">
As you can see, the only difference between this code and the code for the default cache is that you give the cache region a name using the name parameter.
You should know that neither cacheGetProperties() nor cacheSetProperties() can be used to configure the properties for a custom cache in ColdFusion 9.0. Hopefully this is a feature that will be added in a future version of ColdFusion.
If you want to read from or write to a custom cache, you can only do so using the cfcache tag. Here's an example:
ColdFISH is developed by Jason Delmore. Source code and license information available at coldfish.riaforge.org
<!--- attempt to get the artist query from
the custom object cache --->
<cfcache
key="myCustomObjectCache"
action="get"
id="artistQuery"
name="getArtists"
metadata="myMeta">
<!--- if the item isn't there, it'll return null.
In that case, run the query and cache the
results and rerun the data from the db instead --->
<cfif isNull(getArtists)>
<cfquery name="getArtists" datasource="cfartgallery">
SELECT *
from artists
</cfquery>
<cfcache
key="myCustomObjectCache"
action="put"
id="artistQuery"
value="#getArtists#">
</cfif>
<!--- dump the query from cache --->
<cfdump var="#getArtists#">
<!-- dump the cache meta data --->
<cfdump var="#myMeta#">
1<!--- attempt to get the artist query from
2 the custom object cache --->
3<cfcache
4 key="myCustomObjectCache"
5 action="get"
6 id="artistQuery"
7 name="getArtists"
8 metadata="myMeta">
9
10<!--- if the item isn't there, it'll return null.
11 In that case, run the query and cache the
12 results and rerun the data from the db instead --->
13<cfif isNull(getArtists)>
14 <cfquery name="getArtists" datasource="cfartgallery">
15 SELECT *
16 from artists
17 </cfquery>
18
19 <cfcache
20 key="myCustomObjectCache"
21 action="put"
22 id="artistQuery"
23 value="#getArtists#">
24</cfif>
25
26<!--- dump the query from cache --->
27<cfdump var="#getArtists#">
28
29<!-- dump the cache meta data --->
30<cfdump var="#myMeta#">
This code is almost identical to the code we wrote in Part 5 where we introduced the object cache (don't worry about the extra metadata we're pulling using cfcache. We'll cover that later). The only real difference is that here we specify a name for our cache in both cfcache tags by defining it in the key attribute. Key allows us to specify a custom name for our cache. If a cache by that name hasn't been configured in your ehcache.xnl file, ColdFusion will automatically create it using the parameters set in the default cache settings. Remember, you can only work with custom caches using the cfcache tag. None of the cache functions in ColdFusion 9.0 allow you to specify the cache name you want to apply the function to. Go ahead and run the code a few times to verify it's pulling from the custom cache.
There's a lot more advanced stuff that can be configured in the ehcache.xml file such as cache clustering. These topics deserve their own posts, which we'll get to soon. For now, thanks for sticking with the series and I hope you've learned a little more about the ins and outs of cache configuration in ColdFusion 9.
3/16/10 9:46 PM
Hi Rob
Love your posts on ehcache and cf9. One thing i would love to know about is exactly how you setup ehcache.xml files to enable clustering. Im having great difficulty with this.
see: http://groups.google.com.au/group/cfaussie/browse_...
11/21/11 1:16 PM
I do not understand well the ehcache in CF9.
What I want is to have in cache images which are static, and in the same directory.
So if I could say, put that directory in cache (all contained files) that will be great.
Is this possible ?
7/19/12 2:10 PM
Hey Rob, I'm hitting a snag that I hope others may experience and benefit from understanding, if you may have some more wonderful wisdom to share.
I'm finding (in CF9.0.1, Standard) that despite creating a new custom cache in the ehcache.xml, and restarting CF, that it just doesn't seem to be creating that new custom cache.
For instance, I created one that was set to favor far more disk than memory caching, and yet if I name its name as the key in a cfcache, and confirm that it is indeed "working", I never see any updates to the corresponding .index or .data filenames for that custom cachename in windows\temp.
Instead, I suspect that it's using the default cache instead, which given its 10,000 maxelementsinmemory, means it's never writing to disk (yet).
But here's the thing: if I create a custom cache of the same name ("cachetodisk") using the code you offer above, and use that same cachename in a cfcache, then it DOES create and update those files, at least as long as that server is up. Of course we lose that code-created custom cache config on a restart, which is understandable.
It really just feels like CF is ignoring my change in the ehcache.xml (and therefore treating my use of the cache as a "new unnamed cache", as you talk about above). Yet I have looked in the CF logs ([cf]\logs and [cf]\runtime]\logs) and there are no errors related to this creation of a custom cache.
I've also done the dump of cacheGetproperties(), and all that's shown is the 2 default caches (one for template, one for objects). Sad that that dump doesn't offer a name (though perhaps when a custom cache is properly configured, it would).
So, any thoughts on this challenge? I appreciate that there are lots of moving parts and I could be missing something obvious, but I hope the info above shows I've done what I really should. (and there is only one CF instance on the box, so it's not a matter of configuring the wrong one). Thanks for any thoughts.
7/19/12 3:28 PM
Charlie, can you email me your ehcache.xml file, as well as the code you are using to read/write to the cache?
In CF 9, cacheGetProperties() only returns properties for the default template and/or object cache. They didn't add the ability to get properties for custom caches until ColdFusion 10.