Welcome to the Using JCache (JSR-107) with Oracle Coherence screen cast.
My name is Brian Oliver. I work as an Architect with in the Oracle Coherence team and was one of the specification leads for JCache (JSR-107).
In this presentation we’re going to provide a brief introduction to using JCache with Oracle Coherence.
For the most part all this information, together with detailed examples and step-by-step tutorials are available in the Oracle Coherence Developer documentation, but for those of you that would like a quick introduction and don’t want to read too much, this presentation is for you!
The presentation has 4 main sections.
Firstly we’re going to talk introduce the concept of JCache; what it is, where it came from and where to get it. Next we’re going to talk through the main API; look at the methods that are provided and some information on how to use them. After this we’ll look at the steps required to use JCache with Oracle Coherence. Lastly we’ll provide a summary of places to go for more information.
So let’s get started…
What is JCache?
JCache is the newly standardized Caching API for the Java Platform.
Essentially JCache introduces a new Cache interface that allows developers to access Cache-based data-structures configured for an application. If you’re familiar with the Java Map API or one of the many Map API implementations, you’ll be very comfortable with the JCache Cache API.
JCache was developed through the Java Community Process (or JCP), under the careful guidance of the Java Executive Committee (EC).
Note: While we typically use the term JCache to discuss the API, you may also hear people talk about JSR-107. This is the Java Specification Request that JCache was developed under. Should you require detailed information about JCache, often it’s helpful to search online for JSR-107 as well.
Unlike a lot of JSRs which have a single specification lead, JCache was developed with under the leadership of three people, each with different Caching experience, including myself.
Apart from the leads, many large and small companies provided people and resources, each contributing to the development, review and testing of the specification.
Furthermore, numerous individuals, not affiliated with the aforementioned companies, provided valuable contributions to the specification effort.
Ultimately a lot of industry experts were involved in the design and development of JCache.
When we talk about JCache, it’s important to understand that it consists of several distinct parts, not all of which are of use to everyone.
There’s the JCache API (or API) that developers use to interact with JCache implementations. There’s the JCache Reference Implementation (or RI), a compliant implementation of JCache that developers can use for free (it’s open source) to experiment with JCache. There’s the JCache Technology Compatibility Kit (or TCK), that JCache Providers use to test that their implementations are compliant to the specification. And finally there’s the JCache Specification Document (or SPEC), that defines how JCaches should work and can be used.
For the most part, developers using JCache should only be concerned with the API, but reading the SPEC is also important as it defines the behavior of JCache Caches.
Typically only JCache Providers use the RI and TCK, thought there’s nothing stopping developers using the RI in their applications (both are open source).
In terms of JCache specific resources, the following sites provide detail information on JCache, including i). Official downloads for the API, RI, TCK and SPEC. ii). Lists and Contact details for Members of the Expert Group, including SPEC leads (like myself). iii). Access to the source code, including the API, RI, TCK and DEMOs. iv). Forums where the JCache Expert Group and Community can post and answer questions.
Like most modern Java Artifacts, the JCache API is available in the Maven Universe (eg: on Maven Central), through the use of the following GAV coordinates.
As you may have gathered, JCache itself is simply a specification for Caching in Java, with a corresponding API that developers may use. However, those things alone aren’t enough for an application. They require an “implementation of the specification” to work at runtime.
In JCP terms, an entity (person or company) that produces implementations of specifications is typically called a Provider.
Providers and thus their implementations are usually categorized in two ways. Those that produce “compliant implementations” and those that don’t.
Compliant implementations are those that successfully pass the TCK, without modification. Implementations that don’t pass the TCK can’t say they are JCache compliant.
Ultimately compliance is very important for developers. It’s only through using compliant implementations may application developers have the option of swapping to alternative provider implementations. More specifically, compliant implementations allow “application portability”.
Now that you understand the terminology around JCache, let’s take a look at the core JCache API.
However before we start looking at the API, let’s look briefly at an example.
Unlike regular data-structures, like say Maps, Sets and Lists, developers don’t use the new operator to create Caches. Instead developers typically request them from the Caching provider or in a container, they may be injected into an application.
For convenience, JCache provides a simple static method to look up a previously configured and Named Cache for the currently configured Caching Provider. If a Caching Provider isn’t configured an exception will be raised. Likewise if the requested Cache isn’t available and/or isn’t configured with the specified types of keys and values, in this case Integer and String, an exception will also be raised.
Once you have a reference to a Cache, you can perform operations against it. For example, like Map-based data-structures, you can put and get values based on gets.
IMPORTANTLY HOWEVER: While Caches may look like Maps, they aren’t. Caches may expire (ie: lose) data automatically and in the back-ground, based on some external configuration, or indeed, based on system-resources. How this is configured is outside the scope of the specification, but developers using Caches must remember, while they may look like Maps, they may not have the behavior of Maps. For Example: While an application may put a value in a cache, and then attempt to “get” it again, even immediately, the underlying Cache may have already “expired” it, based a configured expiry and/or eviction policy.
Essentially the Cache API looks a lot like the Map API, but with a few differences.
Of course it’s possible to “get” the value of an entry (which returns null if it’s not available).
You can also “getAll” a colleciton of values, given a set of keys.
But additionally you can ask a Cache to “load” a collection of values from a configured CacheLoader, say given a collection of keys.
Likewise, as Caches may hold onto external resources, they are Closable (unlike Maps).
Of course you can “put” values into a Cache (like a Map), but notice it doesn’t return the previous value (like the Map.put method would).
To atomically perform a put and return the previous value you can use the “getAndPut” method.
Similarly you can use “getAndRemove” to remove an existing value.
For the most part the entire Cache interface is designed in such a way that every operation is atomic. Unlike many caching implementations, JCache is explicitly designed for high-performance, low-latency scenarios, in which case, operations that typically introduce latency are not available in the API. For example: entry locking is not supported, however an efficient mechanism to perform atomic operations outside of those provided is available.
Of course you can remove and replace entries, but additionally you can removeAll and clear entries.
While these two methods seem to have the same semantics, there is a subtle difference. When removeAll is called, any listener registered for the Cache will also be notified (at some point in time), where as when “clear” is called, no listeners are notified.
The most unusual or interesting methods on the Cache API are those that deal with Entry Processors.
For the most part you can think of these as custom functions/closures that are atomically executed against one (or more) entries in a Cache. If you’ve been learning Java 8, these provide the ability to execute a lambda function on an entry, potentially mutating the entry, in an atomic manner, without requiring locking or synchronization semantics.
The JCache Specification provides a lot more detail surrounding the semantics of Entry Processors.
If you’re a developer that uses Oracle Coherence, you’ll probably recognize the concept of Entry Processors. Coherence has had them for nearly ten years and due to their popularity we decided to incorporate the concept into JCache.
Unlike Maps, Caches provide the ability for applications to listen and observe changes in Cache data, including insertion, updates, removal and eviction.
The JCache specification also recognizes that for many providers, developers may wish to access the underlying internal implementations a Cache instance may use for implementing the specification. In which case developers are provided with the ability to “unwrap” a JCache Cache to access an internal class. In Coherence terms, this includes being able to access the underlying NamedCache that a JCache Cache may use for it’s implementation. Obviously when doing so, you’re applications would no longer be portable across providers and thus it’s not a recommended activity.
While this is the bulk of the JCache Cache API, there’s actually a lot more to the JCache specification, including;
Providing the ability to use multiple caches, each with different names and types Providing the ability to use multiple providers Providing support for annotation-driven Caching, typically used when deploying applications in Containers (and for injection) Supporting the ability to use JMX to monitor Caches.
As this is meant to be a brief introduction, it’s best to consult the specification documentation on each of these features and capabilities.
Now that we’ve got some background concerning the JCache API, let’s look at how to use it with Oracle Coherence
Oracle Coherence 12.1.3 is one of the first commercially produced and supported compliant JCache Providers.
There are several reasons for this; i). JCache essentially provides a sub-set of functionality that Coherence offers, hence implementing JCache on Coherence is relatively straight forward. ii). The Oracle Coherence support (provider) was developed along side the JCache specification, and mostly completed when the JCache specification become version 1.0
Not only does the Oracle Coherence provider support all of the JCache APIs and out of the box configurations, it adds the ability to use additional (yet compliant) topologies for managing Cache data.
For example: The Local Cache Configuration for a Cache instructs it to keep keys and values in the same “local” Java Virtual Machine as the application creating/using the said Cache.
Where as the Partitioned Cache Configuration for a Cache instructs it to keep keys and values in “partitions”, distributed and managed by a Coherence Cluster.
Note: The JCache specification does not define where Cache data is stored, which means providers like Coherence can optimize storage and representation of data for an application.
The Coherence Developer documentation provides a good summary of common features shared by JCache and Coherence, together with some of the extensions provided by Coherence outside of the JCache specification.
There are five simple steps to using JCache with Coherence (four of which are common regardless of provider)
Step 1: You need to include the appropriate jars on your class path.
NOTE: If you’re using a container-based environment, like Weblogic Server or Managed Coherence Servers, the coherence.jar is already in the classpath
There are five simple steps to using JCache with Coherence (four of which are common regardless of provider)
Step 2: You need to enable JCache for your application (this step is Coherence specific)
To do this you need to either introduce the JCache Namespace into your existing Coherence Cache Configuration or simply use the provided coherence-jcache-cache-config.xml file.
(in a non-container based environment you typically do this with a system property).
Once you’ve configured the class path and cache configuration, the next step is to acquire the Caching Provider implementation, which in this case will be the Coherence Caching Provider.
From this you can then acquire a Caching Manager, that of which can be used to manage caches!
Once you’ve acquired a Cache Manager, you can then define and access caches.
In this example we use the JCache provided MutableConfiguration class to define a Cache Configuration (by default for a local cache). Using the Configuration instance we can set the required properties of the Cache, including storage semantics (like store-by-value) and the key and value types. To learn about the types of configuration possible using MutableConfigurations, refer to the JCache specification and API.
Once you have a suitable configuration, you can use the Cache Manager to create the Cache. Should the Cache already exist, and exception will be thrown.
Now that you have created a Cache, you can use either the Cache Manager or the Caching helper method to request Cache (or use the one returned by the createCache method call).
There’s a lot of information available concerning JCache.
The best places to start learning about JCache is the specification document. This is freely available to download and contains numerous examples, together with detailed explanation of the API. Alternatively you can peruse the JCache API javadoc, which is also very detailed.
When you’re done learning about JCache and you want to learn how to use it with Coherence, the best place to start is working through the information contained in the Developing Applications with Oracle Coherence book, also freely available to download with Coherence.
In this talk we introduced the concept of JCache, the new Caching standard and API for the Java Platform, together with the first steps to use JCache with Oracle Coherence.
Thank you for your time. I hope this brief introduction will inspire you to look further at JCache to standardize your application Caching requirements, together with Oracle Coherence as your preferred JCache Caching Provider.