Deepak Gupta
Deepak Gupta

Reputation: 197

Getting IllegalArgumentException while using jcache with hazelcast

I am trying to use jcache with hazelcast server provider. But getting this exception.

    java.lang.IllegalArgumentException: Cannot find cache named 'xyzCache' for Builder throws caches=[xyzCache] | key='' | keyGenerator='' | cacheManager='' | cacheResolver='' | condition='' | unless='' | sync='false'
    at org.springframework.cache.interceptor.AbstractCacheResolver.resolveCaches(AbstractCacheR esolver.java:81)
    at org.springframework.cache.interceptor.CacheAspectSupport.getCaches(CacheAspectSupport.java:242)
    at org.springframework.cache.interceptor.CacheAspectSupport$CacheOperationContext.<init>(CacheAspectSupport.java:675)
    at org.springframework.cache.interceptor.CacheAspectSupport.getOperationContext(CacheAspectSupport.java:255)
    at org.springframework.cache.interceptor.CacheAspectSupport$CacheOperationContexts.<init>(CacheAspectSupport.java:581)
    at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:327)
    at org.springframework.cache.interceptor.CacheInterceptor.invoke(CacheInterceptor.java:61)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)

Here is the java configuration that I am using to configure hazelcast.

HazelcastConfiguration.java

    @EnableCaching
    class HazelcastConfiguration {

    @Bean
    public Config getConfig() throws FileNotFoundException {
    Config config;

    if ((xmlConfigLocation == null) || (xmlConfigLocation.isEmpty())) {
      // use default Hazelcast configuration
      config = new Config();
    } else {
      // overlay custom xml config on default Hazelcast configuration.
      config = new FileSystemXmlConfig(xmlConfigLocation);
    }
    //Trying to create cache config 
    MapConfig cache = new MapConfig();

    cache.setName("xyzCache");
    cache.getMaxSizeConfig().setSize(1);
    cache.setMaxIdleSeconds(0);
    cache.setTimeToLiveSeconds(86400);
    cache.setEvictionPolicy(EvictionPolicy.LRU);
    config.addMapConfig(cache);
    }
    }

Dependency used:

    <dependency>
          <groupId>com.hazelcast</groupId>  
          <artifactId>hazelcast-spring</artifactId>  
          <version>3.6.8</version>  
       </dependency>  

    <dependency>
          <groupId>com.hazelcast</groupId>  
          <artifactId>hazelcast-cloud</artifactId>  
          <version>3.6.8</version>
       </dependency>

Spring Boot Version: 1.4.6

Using these configuration, i am able to create and use hazelcast cache in application. After adding below dependency to provider jcache cache provider. Spring boot trying to use JCacheCacheConfiguration from its autoconfiguration and its cache manager.

    <dependency>
          <groupId>javax.cache</groupId>
          <artifactId>cache-api</artifactId>
          <version>1.0.0</version>
       </dependency>

Spring Boot starts the application without any exception or error. But as soon as i try to run first api call, it starts throwing me above exception. Any advice.?

Upvotes: 3

Views: 1087

Answers (3)

Vassilis Bekiaris
Vassilis Bekiaris

Reputation: 823

When the javax.cache::cache-api artifact is not in your classpath, Spring Boot backs the cache with a Hazelcast IMap, so your MapConfig is picked up and configures an IMap that holds the cached results for your Cacheable method.

Once the JCache API is located in the classpath, then it attempts to use Hazelcast as a JCache implementation (see [1]). In this case, Spring's JCacheCacheManager attempts to get a Cache already known to the JCache provider, so you need to configure Hazelcast for the cache names you declare in your @Cacheable annotations (see [2] for Hazelcast JCache configuration). For example, for the programmatic configuration you originally posted, when javax.cache::cache-api is in the classpath you need to configure Hazelcast as follows:

@Bean
public Config getConfig() {
    Config config = new Config();
    // do your file stuff here
    CacheSimpleConfig cacheConfig = new CacheSimpleConfig();
    cacheConfig.setName("xyzCache");
    // set other options here
    config.addCacheConfig(cacheConfig);

    // alternatively to creating CacheSimpleConfig and adding it:
    // config.getCacheConfig("xyzCache").setBackupCount(1).set...;
    return config;
}

[1] https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-caching-provider-jcache

[2] http://docs.hazelcast.org/docs/3.9/manual/html-single/index.html#configuring-for-jcache

Upvotes: 0

Ozan Kılı&#231;
Ozan Kılı&#231;

Reputation: 591

It seems you configure the cache via MapConfig. Try to use the config object that returns from config.getCacheConfig("xyzCache"); method in your configuration section, then let's see if it solves the problem.

Upvotes: 1

Yogi
Yogi

Reputation: 1895

Method for setting cache instance is config.setInstanceName("xyzConfig") on Config

So Full code should be like:

@EnableCaching
class HazelcastConfiguration {

@Bean
public Config getConfig() throws FileNotFoundException {
    Config config;

    if ((xmlConfigLocation == null) || (xmlConfigLocation.isEmpty())) {
      // use default Hazelcast configuration
      config = new Config();
    } else {
      // overlay custom xml config on default Hazelcast configuration.
      config = new FileSystemXmlConfig(xmlConfigLocation);
    }

    config.setInstanceName("xyzConfig");

    //Trying to create cache config 
    MapConfig cache = new MapConfig();
    cache.getMaxSizeConfig().setSize(1);
    cache.setTimeToLiveSeconds(86400);
    cache.setEvictionPolicy(EvictionPolicy.LFU);

    // This were you put cache key and value
    config.getMapConfigs().put("xyzCache",cache);
}

Upvotes: 0

Related Questions