Ehcache3's templates

Earlier this month, a week ago more precisely, we’ve released the first alpha of the new development line of Ehcache. The target of the alpha release was to provide a JSR-107, the javax.cache API for java, compliant implementation of using the new API and features as we plan to have them for the v3 of Ehcache.

On-heap caching using the JSR-107 API

We’ve released a heap-only CachingProvider for JSR-107 and will start making the other topologies available with the beta releases early 2015… While the alpha comes with a new API into Ehcache, its main purpose is to enable people to make use of javax.cache APIs. These are obviously frozen, while the Ehcache v3 APIs are still somewhat in flux… Presenting recently on the subject, someone asked:

I noticed there is no way to specify size of cache.

What am I missing? The 107 spec does not talk about size or maxEntries, yet it clearly says “resource constraint” but no constraint configuration is covered in the spec.

Is it even practical to define caches without size?

Well and indeed, no, it’s not practical to define a cache without capacity constraint (it’s just a Map otherwise, right?), but yes, the JSR-107 specification provides no way of configuring a capacity constraint on a Cache (or CacheManager).

Cache template to the rescue!

Ehcache always provided you a way to configure your CacheManager using a XML file, so does this new version. But we’ve added a small feature to our XML configuration: cache template. The idea came out of some crazy thought I had and smart developers pushed further during our public Ehcache weekly dev meeting. Basically cache template are cache definitions that you can “extend” when creating an actual cache. This makes your XML tighter when you create many different caches that only differ a little in terms of configuration. You can read everything about them in this little read me, but here’s how it works in a nutshell:

  1. Define one or multiple named cache-template(s), as if it was a cache, in your XML file;
  2. Define an aliased cache to use that cache-template (referencing it by name);
  3. Optionally override certain attributes from the cache-template.

Here is an example of this:

<ehcache:config
    xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
    xmlns:ehcache='http://www.ehcache.org/v3'>

  <ehcache:cache-template name="example">
    <ehcache:key-type>java.lang.String</ehcache:key-type>
    <ehcache:value-type>java.lang.String</ehcache:value-type>
    <ehcache:capacity>120</ehcache:capacity>
  </ehcache:cache-template>

  <ehcache:cache alias="bar" usesTemplate="example">
    <ehcache:key-type>java.lang.Number</ehcache:key-type>
  </ehcache:cache>
</ehcache:config>

Where cache aliased “bar” extends cache-template “example”, so that it gets its capacity, value-type and key-type… but the key-type is explicitly overwritten.

How’s that useful to my JSR-107 application?

Well, we’ve added a small feature to our JSR-107 CachingProvider that let’s you define programmatically configured caches (at runtime) should use a cache-template. This is all explained in this other read me. But again, in a nutshell:

  1. I have this application that creates a javax.cache.CacheManager programmatically, using either some specific URI to configure it, or the default’s URI (see your provider’s documentation);
  2. At runtime, the app creates a cache named “users”, either using plain javax.cache APIs or some vendor specific configuration object. Either it doesn’t provide any capacity limit, or does it in a vendor specific way that Ehcache wouldn’t understand;
  3. When using Ehcache’s XML configuration, I can define cache-template as mentioned above, but adding the 107 XML configuration extension, I can define that when Cache “users” gets created it gets “enhanced” by a given template.

That way my application can benefit of all Ehcache features without tying itself to any of its APIs. Again, especially useful for exiting applications making use of the JSR-107 APIs (whether using other vendor specific APIs or not). Here’s a small example of the use-case above:

<config
    xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
    xmlns='http://www.ehcache.org/v3'
    xmlns:jsr107='http://www.ehcache.org/v3/jsr107'>

  <service>
    <jsr107:defaults default-template="tinyCache">
      <jsr107:cache name="users" template="usersTemplate"/>
    </jsr107:defaults>
  </service>

  <cache-template name="usersTemplate">
    <capacity>5000</capacity>
  </cache-template>

  <cache-template name="tinyCache">
    <capacity>200</capacity>
  </cache-template>

</config>

Where we also set a defaultTemplate for all other caches created on using that javax.cache.CacheManager.

Try it out!

We’re trying hard to make Ehcache 3 the best JSR-107 provider out there. We actually think we need to address some shortcomings of the specification while doing so… This feature actually came from an issue filed against the Ehcache v2 JSR-107 given some question on our mailing list… So please, try it all out and be vocal! Let us know what you think! In the meantime, we’ll be making progress on the beta release planned for early 2015.