Eric B.
Eric B.

Reputation: 24441

JCache with multiple caching providers?

I intentionally have a couple of different caching providers in my classpath. I have Hazelcast for distributed cache and Caffeine for a local cache. I am trying to use JCache (JSR107) annotations for caching my values.

I have already created a CacheResolverFactory that will be able to detect which cache manager to use from which provider (based on method annotations), but when I launch my application I get the following error message:

Exception in thread "Thread-2" javax.cache.CacheException: Multiple CachingProviders have been configured when only a single CachingProvider is expected
    at javax.cache.Caching$CachingProviderRegistry.getCachingProvider(Caching.java:386)
    at javax.cache.Caching$CachingProviderRegistry.getCachingProvider(Caching.java:361)
    at javax.cache.Caching.getCachingProvider(Caching.java:151)
    at org.jsr107.ri.annotations.DefaultCacheResolverFactory.<init>(DefaultCacheResolverFactory.java:59)
    at org.jsr107.ri.annotations.cdi.CacheLookupUtil.<init>(CacheLookupUtil.java:45)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)

Clearly, I am aware that I have multiple cache providers. However, I cannot seem to find anyway around this issue. The org.jsr107.ri.annotations.cdi.CacheLookupUtil class has a private CacheResolverFactory member which is initialized on construction to the DefaultCacheResolverFactory() which expects a single CacheProvider.

public class CacheLookupUtil extends AbstractCacheLookupUtil<InvocationContext> {
    @Inject
    private BeanManagerUtil beanManagerUtil;
    private CacheKeyGenerator defaultCacheKeyGenerator = new DefaultCacheKeyGenerator();
    private CacheResolverFactory defaultCacheResolverFactory = new DefaultCacheResolverFactory();
...
...
}

Is there anything I can do to circumvent this problem? Can JCache ONLY be used with 1 caching provider? And the CacheLookupUtil class is field @Injected into all the annotation processors.

Is my only choice to override all the interceptors (and provide custom interceptors) and create my own CacheLookupUtil implementation? Or is there something else I can do instead?

Upvotes: 5

Views: 3049

Answers (1)

cruftex
cruftex

Reputation: 5723

JCache supports multiple caching providers.

You need to activate your custom cache provider for the annotation processor. Like this:

@CacheDefaults(cacheResolverFactory=LocalCacheResolver.class)
public class SomeService {
  // methods with caching annotations
}

Note about the RI annotations: I have mixed feelings about the usage. In general its part of the reference implementation of the JCache standard. The whole JCache reference implementation (RI) isn't intended to be used in production and was created to validate the standard. Using the annotation processing of the RI was propagated here by Greg Luck back in 2014, see: How JSR107 Caching Annotations are meant to be used. However, that was meant as an intermediate solution before relevant other implementations become available.

Upvotes: 1

Related Questions