---
---
= The Ehcache 3.x JSR-107 Provider
ifndef::sourcedir39[]
include::{includedir}/common.adoc[]
endif::sourcedir39[]

ifdef::notBuildingForSite[]
include::{includedir}/menu.adoc[]
endif::notBuildingForSite[]

[[overview]]
== Overview of JCache

The Java Temporary Caching API (JSR-107), also referred to as JCache, is a specification (not a software implementation) that defines the javax.cache API.
The specification was developed under the Java Community Process, and its purpose is to provide standardized caching concepts and mechanisms for Java applications.

The API is simple to use, it is designed as a caching standard and is vendor-neutral.
It eliminates the stark contrast that has in the past existed between APIs of different vendors,
which caused developers to stick with the proprietary API they were already using, rather than investigating a new API,
as the bar to investigating other products was too high.

So it is easy for you as an application developer to develop an application using the JCache API from one vendor,
then if you so choose, try out another vendor's JCache support without having to change a single line of your application code.
All you have to do is use the JCache caching library from your chosen vendor.
This means you can avoid having to rewrite a lot of your caching related code in an application just to try out a new caching solution.

[[jcache-provider]]
== Using Ehcache as a JCache Provider

To use JCache API calls in an application, you require both of the following jar files:

* The JCache jar, which defines the JCache APIs.

* The Ehcache jar, which is the caching provider jar that implements the JCache APIs.
It translates the JCache API calls to their Ehcache API equivalent.

You can use the JCache API to develop a complete application, without the need to use any Ehcache API calls.

=== Setting up Ehcache as the Caching Provider for JCache

To use Ehcache as the caching provider for your application, add the file `javax.cache:cache-api:1.x.y.jar` (where `x.y` is a version-dependent string) to your application's classpath.
This is of course assuming Ehcache is already on that same classpath.
No other setup steps are required.

The Ehcache jar file is contained in the product distribution.
The JCache jar file is available as a download from the JSR-107 section of the web pages of the Java Community Process.

NOTE: If you were already using JCache with another caching provider, ensure that you remove the other provider's jar file before starting your application.

[[getting-started]]
== Getting Started with Ehcache and JCache (JSR-107)

In addition to the `Cache` interface, the JCache specification defines the interfaces `CachingProvider` and `CacheManager`.
Applications need to use a `CacheManager` to create/retrieve a `Cache`.
Similarly a `CachingProvider` is required to get/access a `CacheManager`.

Here is a code sample that demonstrates the usage of the basic JCache configuration APIs:

[source%nowrap,java,indent=0]
----
include::{sourcedir39}/107/src/test/java/org/ehcache/docs/EhCache107ConfigurationIntegrationDocTest.java[tag=basicConfigurationExample]
----

<1> Retrieves the default CachingProvider implementation from the application's classpath.
This method will work if and only if there is exactly one JCache implementation jar in the classpath.
If there are multiple providers in your classpath then use the fully qualified name `org.ehcache.jsr107.EhcacheCachingProvider` to retrieve the Ehcache caching provider.
You can do this by using the `Caching.getCachingProvider(String)` static method instead.
<2> Retrieve the default `CacheManager` instance using the provider.
<3> Create a cache configuration using `MutableConfiguration`…​
<4> with key type and value type as `Long` and `String` respectively…​
<5> configured to store the cache entries by reference (not by value)…​
<6> and with an expiry time of one minute defined for entries from the moment they are created.
<7> Using the cache manager, create a cache named jCache with the configuration created in step <3>.
<8> Put some data into the cache.
<9> Retrieve the data from the same cache.

[[integrating-configs]]
== Integrating JCache and Ehcache Configurations

As mentioned already, JCache offers a minimal set of configuration that is ideal for an in-memory cache.
But Ehcache native APIs support topologies that are much more complex and provide more features.
At times, application developers might want to configure caches that are much complex (in terms of topology or features)
than the ones that the JCache `MutableConfiguration` permits, and still be able to use JCache's caching APIs.
Ehcache provides several ways to achieve this, as described in the following sections.

=== Accessing the underlying Ehcache configuration from a JCache configuration

When you create a `Cache` on a `CacheManager` using a `MutableConfiguration` - in other words, using only JCache types -
you can still get to the underlying Ehcache `CacheRuntimeConfiguration`:

[source%nowrap,java,indent=0]
----
include::{sourcedir39}/107/src/test/java/org/ehcache/docs/EhCache107ConfigurationIntegrationDocTest.java[tag=mutableConfigurationExample]
----

<1> Create a JCache cache using the `MutableConfiguration` interface from the JCache specification.
<2> Get to the JCache `CompleteConfiguration`.
<3> Get to the configuration bridge connecting Ehcache and JCache.
<4> Unwrap to the Ehcache `CacheRuntimeConfiguration` type.

=== Building the JCache configuration using Ehcache APIs

==== CacheManager level configuration

If you need to configure features at the `CacheManager` level, like the persistence directory, you will have to use provider specific APIs.

The way you do this is as follows:

[source%nowrap,java,indent=0]
----
include::{sourcedir39}/107/src/test/java/org/ehcache/docs/EhCache107ConfigurationIntegrationDocTest.java[tag=ehcacheCacheManagerConfigurationExample]
----
<1> Cast the `CachingProvider` into the Ehcache specific implementation `org.ehcache.jsr107.EhcacheCachingProvider`,
<2> Create a configuration using the specific Ehcache `DefaultConfiguration` and pass it some `CacheManager` level configurations,
<3> Create the `CacheManager` using the method that takes an Ehcache configuration as a parameter.

==== Cache level configuration

You can also create a JCache `Cache` using an Ehcache `CacheConfiguration`.
When using this mechanism, no JCache `CompleteConfiguration` is used and so you cannot get to one.

[source%nowrap,java,indent=0]
----
include::{sourcedir39}/107/src/test/java/org/ehcache/docs/EhCache107ConfigurationIntegrationDocTest.java[tag=ehcacheBasedConfigurationExample]
----

<1> Create an Ehcache `CacheConfiguration`.
You can use a builder as shown here, or alternatively use an XML configuration (as described in the following section).
<2> Get a JCache configuration by wrapping the Ehcache configuration.
<3> Get back to the Ehcache `CacheConfiguration`.
<4> ... or even to the runtime configuration.
<5> No JCache `CompleteConfiguration` is available in this context.

==== Building the JCache configuration using an Ehcache XML configuration

Another way to have the full Ehcache configuration options on your JCache caches while having no code dependency on Ehcache
as the cache provider is to use XML-based configuration.
See <<xml.adoc#,the XML documentation>> for more details on configuring `Cache`s in XML.

The following is an example of an XML configuration:

[source%nowrap,xml,indent=0]
----
include::{sourcedir39}/107/src/test/resources/org/ehcache/docs/ehcache-jsr107-config.xml[]
----

Here is an example of how to access the XML configuration using JCache:

[source%nowrap,java,indent=0]
----
include::{sourcedir39}/107/src/test/java/org/ehcache/docs/EhCache107ConfigurationIntegrationDocTest.java[tag=jsr107UsingXMLConfigExample]
----

<1> Invoke `javax.cache.spi.CachingProvider.getCacheManager(java.net.URI, java.lang.ClassLoader)`
<2> ... and pass in a `URI` that resolves to an Ehcache XML configuration file.
<3> The second argument is the `ClassLoader` to use to load user types if needed;
i.e. `Class` instances that are stored in the `Cache` managed by our `CacheManager`.
<4> Get the configured `Cache` out of the `CacheManager`.

[NOTE]
====
You can alternatively use the `CachingProvider.getCacheManager()` method that takes no arguments.
The `URI` and `ClassLoader` used to configure the `CacheManager` will then use the vendor specific values
returned by `CachingProvider.getDefaultURI` and `.getDefaultClassLoader` respectively.
Be aware that these are not entirely specified for Ehcache currently and may change in future releases!
====

==== Enabling/Disabling MBeans for JCache using an Ehcache XML configuration

When using an Ehcache XML configuration, you may want to enable management and / or statistics MBeans for JCache caches.
This gives you control over the following:

* `javax.cache.configuration.CompleteConfiguration.isStatisticsEnabled`

* `javax.cache.configuration.CompleteConfiguration.isManagementEnabled`

You can do this at two different levels:

[source%nowrap,xml,indent=0]
----
include::{sourcedir39}/107/src/test/resources/org/ehcache/docs/ehcache-107-mbeans-cache-manager-config.xml[lines=17..-1]
----

<1> Using the JCache service extension, you can enable MBeans by default.
<2> The cache `stringCache` will have both MBeans enabled, according to the service configuration.
<3> The cache `overrideCache` will have both MBeans disabled, overriding the service configuration.
<4> The cache `overrideOneCache` will have the statistics MBean disabled, whereas the management MBean will be enabled according to the service configuration.

[[supplement-jsr-107-configurations]]
==== Supplementing JCache cache configurations using Ehcache XML extensions

You can also create `cache-templates`.
See the <<xml.adoc#cache-template-elements,Cache Templates>> section of the XML Documentation for more details.
Ehcache as a caching provider for JCache comes with an extension to the regular XML configuration so you can:

* Configure a default template from which all programmatically created `Cache` instances inherit, and
* Configure a given named `Cache` to inherit from a specific template.

This feature is particularly useful to configure `Cache` beyond the scope of the JCache specification, for example, giving `Cache` a capacity constraint.
To do this, add a `jsr107` service in your XML configuration file:

[source%nowrap,xml,indent=0]
----
include::{sourcedir39}/107/src/test/resources/org/ehcache/docs/ehcache-jsr107-template-override.xml[]
----

<1> First, declare a namespace for the JCache extension, e.g. `jsr107`.
<2> Within a service element at the top of your configuration, add a `jsr107:defaults` element.
<3> The element takes an optional attribute `default-template`, which references the `cache-template` to use for all `javax.cache.Cache` elements created by the application at runtime using `javax.cache.CacheManager.createCache`.
In this example, the default `cache-template` used will be `tinyCache`, meaning that in addition to their particular configuration, any programmatically created `Cache` instances will have their capacity constrained to 20 entries.
<4> Nested within the `jsr107:defaults` element, add specific `cache-templates` to use for the given named `Cache`.
So, for example, when creating the `Cache` named foos at runtime, Ehcache will enhance its configuration, giving it a capacity of 2000 entries, as well as ensuring that both key and value types are `String`.

NOTE: The XSD schema definitions that describe the syntax used for the Ehcache XML configuration are referenced at
<<xsds#,Ehcache XSDs>>.

Using the above configuration, you can not only supplement but also override the configuration of JCache-created caches without modifying the application code.

[source%nowrap,java,indent=0]
----
include::{sourcedir39}/107/src/test/java/org/ehcache/docs/EhCache107ConfigurationIntegrationDocTest.java[tag=jsr107SupplementWithTemplatesExample]
----

<1> Assume existing JCache configuration code, which is store-by-value by default
<2> ... that creates JCache `Cache`.
<3> If you were to get to the Ehcache `RuntimeConfiguration`
<4> ... you could verify that the template configured capacity is applied to the cache and returns 20 here.
<5> The cache template will override the JCache cache's store-by-value configuration to store-by-reference, since the `byRefTemplate` that is used to create the cache is configured explicitly using `IdentityCopier`.
<6> Templates will also override the JCache configuration, in this case using a configuration with Time to Live (TTL) 1 minute.
<7> Create a cache where the template sets the TTL to 2 minutes.
<8> And we can indeed verify that the configuration provided in the template has been applied; the duration will be 2 minutes and not 1 minute.
<9> One drawback of this is that when getting at the `CompleteConfiguration`, you no longer have access to the factories from JCache.

[NOTE]
====
As mentioned in step 5, in order to override the store-by-value configuration of a JCache cache using templates, you can explicitly configure the template using `IdentityCopier`.
But the usage of `IdentityCopier` is not mandatory to get a store-by-reference cache.
You can use any custom copier implementation that does not perform any _copying_ but returns the exact same reference that gets passed into the copy methods.
`IdentityCopier` is just an example that we have provided for your convenience.
====

== Differences in Default Behavior between Ehcache and Ehcache through JCache

Ehcache used natively and Ehcache used through JCache do not always agree on default behavior.
While native Ehcache can behave the way JCache specifies, depending on the used configuration mechanism, you may see differences in defaults.

=== by-reference or by-value

Ehcache and Ehcache through JCache disagree on the default mode for heap-only caching.

=== Ehcache configuration with JCache `MutableConfiguration`

Unless you invoke `MutableConfiguration.setStoreByValue(boolean)`, the default value is _true_.
This means that you will be limited to `Serializable` keys and values when using Ehcache.

Under the cover, this will trigger the use of <<serializers-copiers#copiers-bundled, serializing copiers>>
and pick the appropriate serializer from the <<serializers-copiers#serializers-bundled,default ones>>.

=== Ehcache configuration with native XML or code

* Heap only: When using heap only caches, the default is _by-reference_ unless you configure a `Copier`.

* Other tiering configuration: When using any other tiers, since serialization comes into play the default is _by-value_.

See the sections <<serializers-copiers#,Serializers and Copiers>> for related information.

=== Cache-through and compare-and-swap operations

Ehcache and Ehcache through JCache disagree on the role of the cache loader for compare-and-swap operations.

=== Ehcache through JCache behaviour

When using compare-and-swap operations, such as `putIfAbsent(K, V)`, the cache loader will not be used if the cache has no mapping present.
If the `putIfAbsent(K, V)` succeeds then the cache writer will be used to propagate the update to the system of record.
This could result in the cache behaving like INSERT but effectively causing a blind update on the underlying system of record.

=== Native Ehcache behaviour

The `CacheLoaderWriter` will always be used to load missing mappings with and to write updates.
This enables the `putIfAbsent(K, V)` in cache-through to behave as an INSERT on the system of record.

If you need _Ehcache through JCache_ behaviour, the following shows the relevant XML configuration:

[source%nowrap,xml,indent=0]
----
include::{sourcedir39}/107/src/test/resources/org/ehcache/docs/ehcache-jsr107-cache-through.xml[tag=cacheThroughCAS]
----
