Three approaches to using JCache (without JavaEE 8)
JSR-107 (aka JCache) specifies API and semantics for temporary, in-memory caching of Java objects in order to standardize most common caching use cases. This JSR took a long time to complete and was not able to be part of JavaEE 7. It is nevertheless a candidate for JavaEE 8, which should be released sometime in the (late) second half of 2017. However, with a little bit of effort, it is already possible to use JCache in Java applications so that when you are able to update to JavaEE 8, your code will already be working according to the standard and you will only need to get rid of dependencies rather than change your cache managing code. In this post I will show you three different ways how to accomplish that.
The example application
I created an example application, which simulates getting the balance of a guest in a hotel. The main service calls other services for different billing areas of the hotel (e.g. spa, pool, room service, etc.) and aggregates the amounts to come up with a total balance for a given guest.
LOGGER.info("Guest balance not found in cache.");
return"Balance for guest "+id+" is $"+balance;
The service is made available on the following REST API:
The application is only a simulation of calling slow services synchronously. That is why each service always returns a fixed amount after waiting a number of milliseconds. This way we can very easily tell by the response times when we are getting a result taken from the cache.
@CacheRemove annotates a method and removes the value identified by the given key from the cache
@CacheRemoveAll annotates a method and removes all the objects of the cache specified in this or in the class annotation.
Now let’s take a look at how we can get these annotations to work.
Approach 1: Taking matters into your own hands
If you want to add support for JCache to an application that runs on a JavaEE compliant application server, you currently do not have any shortcuts and need to do everything on your own. Start off by adding the java cache API and the reference implementation of the cache annotations to your project as dependencies.
If you call the API a second time with the same guest ID, you should get the result a lot faster and nothing will be written to the log.
Approach 2: Getting everything handed to you on a silver platter
The Payara application server is derived from glassfish with many enhancements on top, including a JCache implementation and Hazelcast out of the box, which means the configuration efforts are minimal. The jcache-payara project does not only create a .war file like the first example, but it packages it together with payara micro to create an uber-jar. This way we do not need to start an application server and deploy the application on top of it. We simply run the resulting jar with
To create the microservice we need the following dependencies:
The application will behave identically to the one in the previous approach.
Approach 3: The spring boot way
Even though spring has its own cache abstraction and therefore its own caching annotations, they also offer JCache support, thus enabling the use of standard annotations. All you need to do is add the JCache dependency to your spring boot project…
To build the jar for the jcache-spring application run
./gradlew clean build
And to run the application
Now you can call the API
I just showed you three approaches in which you can use the JCache API without having to wait for JavaEE 8. The decision on which approach to use depends very much on the application on which it will be used. If you want to use JCache on a new application, then you might be able to choose one of the easier options shown instead of taking the long approach. However if your application already exists it might be very costly to make a big change to it solely because of JCache, so you probably will have to choose the approach that is the most similar to your current technology stack.