Получение исключения IllegalArgumentException при использовании jcache с hazelcast

Я пытаюсь использовать jcache с поставщиком сервера hazelcast. Но получаю это исключение.

    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)

Вот конфигурация Java, которую я использую для настройки 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>
          <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>

Весенняя загрузочная версия: 1.4.6

Используя эту конфигурацию, я могу создавать и использовать кеш hazelcast в приложении. После добавления приведенной ниже зависимости к провайдеру jcache cache provider. Весенняя загрузка пытается использовать JCacheCacheConfiguration из своей автоконфигурации и своего диспетчера кеша.

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

Spring Boot запускает приложение без каких-либо исключений или ошибок. Но как только я пытаюсь запустить первый вызов API, он начинает выдавать мне исключение выше. Любой совет.?


person Deepak Gupta    schedule 24.10.2017    source источник


Ответы (3)


Кажется, вы настраиваете кеш через MapConfig. Попробуйте использовать объект конфигурации, который возвращается из метода config.getCacheConfig("xyzCache"); в вашем разделе конфигурации, а затем посмотрим, решит ли он проблему.

person Ozan Kılıç    schedule 24.10.2017
comment
Означает ли это, что jcache с hazelcast работает, когда установлен любой cacheconfig? Что, если нам придется использовать MapConfig, тогда он не будет работать? - person Deepak Gupta; 27.10.2017
comment
Карта и кэш — это разные структуры данных в Hazelcast. Если вы настроите MapConfig и вызовете кеш с тем же именем, вы получите нуль. - person Ozan Kılıç; 30.10.2017
comment
Да, я получаю null при настройке MapConfig. Есть ли способ придерживаться MapConfig при настройке jcache с помощью hazelcast? - person Deepak Gupta; 16.11.2017
comment
Нет, это отдельная структура данных, такая как IQueue. Но зачем вам настраивать IMap при использовании ICache? Есть ли какое-либо требование, которое предоставляет MapConfig, но не другое? - person Ozan Kılıç; 17.11.2017

Метод настройки экземпляра кеша: config.setInstanceName("xyzConfig") в Config.

Итак, полный код должен выглядеть так:

@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);
}
person Yogi    schedule 24.10.2017

Когда артефакт javax.cache::cache-api отсутствует в вашем пути к классам, Spring Boot поддерживает кеш с помощью Hazelcast IMap, поэтому ваш MapConfig подбирается и настраивает IMap, который содержит кэшированные результаты для вашего метода Cacheable.

Как только JCache API находится в пути к классам, он пытается использовать Hazelcast в качестве реализации JCache (см. [1]). В этом случае Spring JCacheCacheManager пытается получить Cache, уже известный провайдеру JCache, поэтому вам нужно настроить Hazelcast для имен кеша, которые вы объявляете в аннотациях @Cacheable (см. [2] для конфигурации Hazelcast JCache). Например, для программной конфигурации, которую вы изначально опубликовали, когда javax.cache::cache-api находится в пути к классам, вам необходимо настроить Hazelcast следующим образом:

@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

person Vassilis Bekiaris    schedule 31.10.2017