It has been a while since the last release, so this release is rather meaty. Most of the changes and new lines of code are for the upcoming persistence support. Persistence is still unfinished, there is a lot of restructuring and stabilising going on. Here are the highlights.
No dependencies
The dependencies on a logging framework and the JSR305 annotations package were removed. The JSR305 annotations are useful, but the spec is unfinished or “dormant” as the JCP page states. Using the annotations within the cache2k API would have meant that these annotations “sneak into” all applications that use cache2k. Bad idea!
From now on we will try to keep a “no dependencies” policy. If we need a dependency, then it is optional and/or a separate Maven module.
Logging abstraction
There is a simple logging abstraction. By default java.util.logging is used. If Apache Commons Logging is present, all output is routed through Commons Logging. I have plans to switch to SLF4J in the future. Vote for it in GitHub issue 7.
New interface for the expiry policy
The interface to determine the entry expiry received a major overhaul. The old interface is still present but will be removed in the near future.
Exception support
Version 0.19 already had support for exceptions. In a read through configuration, exceptions from the cache source
are cached and rethrown wrapped in a PropagatedCacheException. Caching exceptions needs some deeper elaboration, I will
spend a separate blog entry on that.
Android support
For Android support we switched back to language level 1.6. The only thing I really miss is the diamond operator.
All code that needs packages below javax.* which are not available on Android, especially the JMX support,
went to another module (cache2k-ee). If you want an Android compatible cache, use the following Maven POM snippet:
<dependency>
<groupId>org.cache2k</groupId>
<artifactId>cache2k-api</artifactId>
<version>${cache2k-version}</version>
</dependency>
<dependency>
<groupId>org.cache2k</groupId>
<artifactId>cache2k-core</artifactId>
<version>${cache2k-version}</version>
<scope>runtime</scope>
</dependency>
If you want to have a full featured cache, use this:
<dependency>
<groupId>org.cache2k</groupId>
<artifactId>cache2k-api</artifactId>
<version>${cache2k-version}</version>
</dependency>
<dependency>
<groupId>org.cache2k</groupId>
<artifactId>cache2k-ee</artifactId>
<version>${cache2k-version}</version>
<scope>runtime</scope>
</dependency>
Configuration for “tunable constants”
Within the cache2k implementation there are a lot of constants. One example is the hash load factor, which is 64 percent by default. While there is no need to change this value, it feels unwise to bury such values deep in the code and have no mechanism to change them. This magic number and others are factored out and there is some documentation for them on the implementing class. Look out for the Tunable subclass.
It is possible to change these values by providing a properties file at /org/cache2k/tuning.properties.
Here is some example content:
# increase load factor to save memory
org.cache2k.impl.BaseCache.Tunable.hashLoadPercent=80
# switch off randomization for tests
org.cache2k.impl.BaseCache.Tunable.disableHashRandomization=true
For the normal usage of cache2k there is no need to change or tune such a value. This mechanism is intentionally totally decoupled from the normal cache configuration. Maybe this concept proves useful to provide a “tuning” for different platforms and CPU architectures, like Android, Java 7, amd64, PowerPC, etc.
The fine print: The “tunable constants” configuration is not an official API, so there will be no notice of changes.
Iteration
The method Cache.iterator() was added. It supports a fully concurrent iteration of the cache contents.
The iterator also implements the Closeable interface. After the iteration is finished or the iterator is not used any more,
it is best to close it to free resources immediately.
Persistence preview
The persistence support is not finished yet and should be considered “alpha level”. It is included and can be tested. The upcoming release will finalise the persistence support. Maybe it is ready for Christmas?
The default and so far only persistence implementation writes the data to a single file and
keeps the index with the keys in the Java heap. To activate persistence simply add persistence()
to the configuration builder. Some options are available, see
JavaDoc StorageConfiguration.Builder.
Complete list of changes
You will find the brief list of changes in the 0.20 release notes.
Update 2026: Typo and wording fixes, switch to UK English.