This chapter provides an overview of the Coherence implementation of the JSR-107 JCACHE - Java Caching API specification. The specification and API is commonly referred to as JCache in this documentation. A JCache overview section is also provided and includes a basic introduction to the API. For complete details about the API, download the JCache specification, Java sources, and JavaDoc from the Java Community Process (JCP) website:
This chapter includes the following sections:
Coherence includes a JCache provider implementation (
COHERENCE_HOME\lib\coherence-jcache.jar). JCache is a common API for using caching in Java. Application developers use the JCache API (
javax.cache.*) and Coherence provides the underlying caching capabilities. The provider-based approach guarantees cross-provider portability and allows developers to focus on application logic rather than creating and managing complex caching systems. For additional information about JCache, see "JCache Primer".
The Coherence JCache provider uses existing Coherence technology and can be thought of as a wrapper for the Coherence
NamedCache API. This allows Coherence to reuse and expose many of its best-in-class technologies through JCache interfaces.
The Coherence JCache provider offers three cache types:
Local Cache – A cache that is local to an application process. Entries that are stored in local caches do not persist after an application process ends. A local cache is similar to a
NamedCache cache that is configured using a local-scheme cache definition. The local cache implementation is defined in the
com.tangosol.coherence.jcache.localcache package. For details about creating local caches, see "Creating Local Caches".
Partitioned Cache – A cache that is partitioned (distributed) among multiple processes in a Coherence cluster. Entries that are stored in partitioned caches are backed up and persist on the cluster after an application process ends. A partitioned cache is similar to a
NamedCache cache that is configured using a distributed-scheme cache definition. The partitioned cache implementation is defined in the
com.tangosol.coherence.jcache.partitionedcache package. For details about creating partitioned caches, see "Creating Partitioned Caches". To learn more about partitioned caches, see "Understanding Distributed Caches".
Pass-Through Cache – A cache that delegates to an existing
NamedCache cache. Pass-through caches offer applications the ability to use all Coherence native features from a JCache interface. Pass-through caches are ideal for applications that want to migrate to JCache but also want to reuse their existing Coherence application components. The pass-through cache implementation is defined in the
com.tangosol.coherence.jcache.passthroughcache package. For details about creating pass-through caches, see "Creating Pass-Through Caches".
The Coherence JCache provider uses the native Coherence event APIs to implement JCache events. The local and partitioned cache implementations leverage the Coherence
MapListener API. The pass-through cache implementation only supports the Coherence
MapEvents that map directly to the JCache events and there is no support for JCache expired events. Each cache type is responsible for registering map listeners and for dispatching map events. Event classes are located in the com.tangosol.coherence.jcache.common package as well as in each cache type package. For details about creating and using JCache events, see "Using JCache Events".
There is no equivalent of the
javax.cache.event.CacheEntryExpiredListener API in the Coherence
NamedCache.clear method results in a Coherence
MapListener.entryDeleted event; however, the JCache
Cache.clear method does not result in any events.
The Coherence JCache provider uses the native Coherence
InvocableMap.EntryProcessor API to implement JCache entry processors. Each cache type includes an
InvokeProcessor class in their respective
processors package that is responsible for executing JCache entry processors when the
invokeAll methods are called from a cache. For details about creating and using JCache entry processors, see "Processing JCache Entries".
processors package for each cache type also includes many native Coherence entry processors that are used to perform cache operations. For example, when using a partitioned cache, the use of the
put method results in the use of the
The Coherence JCache provider makes use of Coherence Portable Object Format (POF) serialization. POF is a proven binary format within Coherence and is efficient in both space and time. For partitioned and pass-through caches, many cache operations utilize POF. Cache configuration, entry processors, event listeners and filters, and JCache statistics also make use of POF.
POF is also used to provide serialization as required by parts of the JCache specification. The
com.tangosol.coherence.jcache.serialization package includes POF serializer implementations to support JCache factory builders, expiry policies, and cache entry listener configuration.
Lastly, applications can choose to use POF for serialization as required; however, it is not a requirement when using the Coherence JCache provider. In use cases where portability between cache providers is a requirement, applications should use Java serialization.
The Coherence JCache provider implements the JCache
CacheStatisticsMXBean MXBean interfaces. The implementation are located in the
com.tangosol.coherence.jcache.common package. Management information for local and partitioned caches are registered to the default MBean server and are found under the
javax.cache namespace. Management information for pass-through caches are reported using the native Coherence JMX management implementation. For details about enabling JCache management, see "Viewing JCache Management Information".
The Coherence JCache provider offers support for many features that are also available with the Coherence native
NamedCache API. However, not all features are available through JCache. Table 33-1 shows a comparison of the two APIs.
Applications that use JCache and the Coherence JCache provider must include the following libraries on the application classpath:
COHERENCE_HOME\lib\cache-api.jar – The standard JCache API.
COHERENCE_HOME\lib\coherence-jcache.jar – The Coherence JCache provider implementation.
COHERENCE_HOME\lib\coherence.jar – The core Coherence library.
The Coherence JCache provider includes a service definition in the
META-INF/services directory of the
coherence-jcache.jar library. The definition allows Coherence to be automatically loaded and used as the default caching provider by applications that use the
javax.cache.Caching bootstrap class. For details about using Coherence as the default JCache provider, see"Specifying Coherence as the JCache Provider".
The JCache provider utilizes the same configuration files as the native Coherence NamedCache API. However, the need to customize the configuration files has been simplified and in some cases not required at all. The following lists the configuration file used by the JCache implementation:
tangosol-coherence-override.xml – A Coherence operational override file is used when configuring a Coherence cluster for partitioned caches and when using pass-through caches. The override file is not required for local caches. For details about operational override files, see "Specifying an Operational Configuration File".
coherence-jcache-cache-config.xml – A Coherence JCache provider-specific cache configuration file that is called
coherence-jcache-cache-cofig.xml is included in the provider JAR file and used to create local and partitioned caches; however, applications are not expected to edit the configuration. The included cache configuration file defines a
JCacheNamespace handler class that is used to programmatically define local and partitioned caches for use by JCache applications.
coherence-jcache-pof-config.xml – A Coherence JCache provider-specific POF configuration file that is called
coherence-jcache-pof-cofig.xml is included in the provider JAR file and is used to define JCache POF types. For details about including JCache POF types with an existing Coherence application, see "Configuring a JCache POF Configuration file".
This section provides an overview of the JCache specification and API and is intended for those that are new to JCache. It includes basic concepts that are used when completing the instructions in this book. If you are familiar with JCache, you can skip this section.
This section is not intended to replace the specification or the API documentation. For complete details, download the JCache specification, Java sources, and JavaDoc from the Java Community Process (JCP) website:
The JCache specification defines an API for creating and using caches in Java programs. Applications often use caches to store and reuse resources that require a significant cost to create. Applications can then quickly access the resources in memory without having to incur the cost associated with recreating the resources. Applications commonly use caching to increase application performance, availability, and scalability.
The JCache API defines a provider-based model for caching. The provider model separates the cache client API from the cache implementation. Applications use a well-defined client API and cache providers are responsible for the actual cache implementation. The provider-based model frees application developers from having to create and manage complex caching sub-systems and ensures portability between cache providers that implement the specification.
The JCache API defines the
CacheManager interfaces. Applications use the
CachingProvider interface to get and use a cache manager. Applications use the
CacheManager interface to create and use caches. Applications are free to use multiple cache providers. However, a cache manager can only be associated with a single cache provider.
JCache offers several ways to get cache providers and access cache managers. A common access pattern that is used throughout this documentation is to use the
Caching bootstrap class. The class provides a convenient way to get a
CachingPovider implementation and automatically discovers providers that include a standard Java service definition.
The following example gets a default
CachingProvider implementation and then creates a cache manager:
CachingProvider cachingProvider = Caching.getCachingProvider(); CacheManager cacheManager = cachingProvider.getCacheManager();
The JCache API defines a
Cache interface. The
Cache interface creates a data structure that stores key and value pairs. Each key and value pair is referred to an entry and is defined by the
Cache.Entry interface. A cache is similar to a Java
Map data structure; However, there are some key differences:
Keys or values cannot be null.
Cache.put operations do not return an entry's previous value. The
Cache.getAndPut operation is functionally equivalent to the
Cache Entries expire and can be evicted.
Values can be automatically loaded from, and written to, an external source to support read-through and write-through caching.
Cache entry changes can be observed.
Cache statistics can be collected.
Cache interface includes methods for putting, getting, replacing, and removing cache entries. Methods are also provided for loading a cache, registering cache listeners, and invoking entry processors.
The following example demonstrates using a cache manager to create a
Cache instance called
Cache<String, Integer> cache = cacheManager.createCache("MyCache", config);
JCache makes use of generics to support both compile and runtime type checking. The example creates a cache that requires keys to be of type
String and values to be of type
Integer. Type checking is not required but is often a best practice.
Operations are performed on the cache instance:
String key = "k"; Integer value = 1; cache.put(key, value);
The JCache API defines the
CompleteConfiguration interface that is used to configure a cache. The
MutableConfiguration class is a default implementation of the interface. The configuration options include:
setting store-by semantics (by value or by reference)
setting cache entry types
setting cache expiry
enabling read-through and write-through caching
enabling management and statistics
Caches are configured when the cache is created. In the previous cache example, the
createCache method required both a name and configuration for the cache. The following example demonstrates creating a configuration object to be used by the
MutableConfiguration<String, Integer> config = new MutableConfiguration<String, Integer>(); config.setStoreByValue(true).setTypes(String.class, Integer.class) .setReadThrough(true) .setWriteThrough(true) .setManagementEnabled(true) .setStatisticsEnabled(true) .setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(Duration.FIVE_MINUTES)); Cache<String, Integer> cache = cacheManager.createCache("MyCache", config);
The JCache API provides multiple interfaces that give applications the ability to customize caching. To use an implementation, you must use the
Factory interface to create the instance. This ensures that the instance is serializable. The following interfaces can be implemented by an application:
ExpiryPolicy – This interface is used to define when (
Duration) cache entries expire based on entry creation, access, and modification operations.
CacheLoader – This interface is used to load data into a cache from an external resource as is required when using read-through caching.
CacheWriter – This interface is used to write data to an external resource as is required when using read-through caching.
CacheEntryListener – A set of subinterfaces (
CacheEntryExpiredListener) that are used to receive and react to Cache events.
EntryProcessor – This interface is used to perform compound operations on cache entries in an atomic, lock-free manner. Unlike the other interfaces, the
EntryProcessor interface does not require the use of the
Factory interface to create an instance; however, the implementation will need to be serialized if the intention is to use distributed caching.
The JCache API defines two dynamic MBeans that are used to manage caches. The
CacheMXBean MXBean reports cache configuration information. The
CacheStatisticsMXBean MXBean reports cache performance statistics that are used to troubleshoot potential issues. The dynamic MBeans are registered with an implementation-specific MBean server and are obtained using standard JMX; including, the use of any JMX MBean-compliant browser.