«Top»

The following introduces JSR 107,
which is an attempt to standardize Java caching functionality.

JSR 107 started in 2001 and has long been idle. The work on JSR 107
gained momentum in 2012 in an
unsuccessful
attempt to become part of JEE 7. The API is now expected to be finalized with
JEE 8.

Most Important Line of Code

The JSR is still not finalized. However, some basic terms appear in any of the
current cache implementations, and are likely to become part of the final
standard.

The main part of JSR 107 centers around the following example code line:

Cache cache = cacheManager.getCache("Greg's Cache");

In this line, the two major classes of JSR 107’s cache architecture
are shown: Cache and CacheManager.

The following describes JSR 107’s view on Cache and CacheManager.

javax.cache.Cache

The cache provides functionality similar to
java.util.concurrent.ConcurrentMap.
As defined in the JavaDoc, ConcurrentMap is a Map
providing additional atomic putIfAbsent, remove, and replace methods.

The Map-based reference implementation
of our example application uses two of ConcurrentMap’s methods:

The most important aspect about these methods is that they are atomic,
i.e. they are either successful, or have no effect.

One difference between ConcurrentMap and Cache is that Cache’s keys
and values must be Serializable
in most configurations.

Internally, JSR 107 Caches are proxy objects that are backed by
configuration-specific CacheLoader and CacheWriter implementations.
In read-through mode, the CacheLoader is capable of transparently
retrieving values on cache misses, in write-through mode the
CacheWriter performs write operations.

javax.cache.CacheManager

The CacheManager manages the Cache’s life cycle, i.e. it initializes
and shuts down background services needed for distributed caches
to operate.

In the example applications, this can be seen in the implementation
of contextInitialized()
and contextDestroyed().

In most cases, CacheManager is used as a Singleton.

Transactions

(optional)

Apart from managing the Cache’s life cycle, the CacheManager also
acts as an XA resource for local transactions.

UserTransaction utx = cacheManager.getUserTransaction();
utx.begin();
// do work
cache.put("key", "value");
// commit
utx.commit();

In that case, the transaction boundary is the CacheManager.

JSR 107 defines global XA transactions as well:

UserTransaction utx = jndiContext.lookup("java:comp/UserTransaction");

Global transactions may be distributed among multiple XA resources.

Next

In the next pages of part 02 of our series, we will modify our
example application
and replace the ConcurrentMap with a local cache: