This post is about a specific problem I encountered using the WildFly application server in combination with the Infinispan cache module, CDI and the JCache API. If you don’t use this combination of technologies this post is probably not relevant or interesting to you, but I hope it will help someone who encounters the same problem.
The problem
After upgrading an application from WildFly 10 to WildFly 13 it became apparent that the settings for the Infinispan caches from the WildFly configuration file are no longer applied to the caches used by the application.
The cache settings in the WildFly configuration specify a cache container, several local caches and the object memory sizes and expiration lifespans of these caches:
<subsystem xmlns="urn:jboss:domain:infinispan:6.0"> <cache-container name="myapp" default-cache="default" module="org.wildfly.clustering.web.infinispan" statistics-enabled="true"> <local-cache name="default" statistics-enabled="true"> <object-memory size="10000"/> <expiration lifespan="86400000"/> </local-cache> <local-cache name="foo" statistics-enabled="true"> <object-memory size="10000"/> <expiration lifespan="600000"/> </local-cache> </cache-container> </subsystem>
The cache manager is injected via CDI resource injection in a Config
class as the default cache manager:
class Config { @Produces @Resource(lookup = "java:jboss/infinispan/container/myapp") private EmbeddedCacheManager defaultCacheManager; }
The caches are used via the @CacheResult
annotation from the JCache API (JSR-107):
class FooService { @CacheResult(cacheName = "foo") public List<Foo> getFoo(String query) { // ... } }
With this setup the application worked, the service results were cached, but the cache settings from the configuration file were not applied, as could be seen by inspecting the MBeans of the caches via JConsole. Instead the caches used a default configuration with an expiration lifespan of -1 (never), even though they were assigned to the cache container “myapp” as configured.
The solution
One particular answer to a similar problem description on StackOverflow was helpful in finding the solution. Each cache must be injected once via CDI resource lookup as well:
import org.infinispan.Cache; class Config { @Resource(lookup = "java:jboss/infinispan/cache/myapp/foo") private Cache<String, Object> fooCache; // ... }
The format of the JNDI path is:
"java:jboss/infinispan/cache/${cacheContainerName}/${cacheName}"
The property itself will be unused, but the @CacheResult
annotation will now use the cache with the correct configuration.
Thanks for the post. It was very helpful but unfortunately does not work on WF 20