在一个正在运行的应用程序上,我试图从Hazelcast 3.6升级到3.12.4,并且遇到一些问题,当两个或多个测试一起运行时,这些问题很容易重现。测试全部用@WebAppConfiguration
注释,并包括使用ContextConfiguration(classes = {AppConfig.class})
作为配置的一部分,我有一个名为@Bean
的{{1}},它将启动CacheAwareStorage
。初始化是非常基本的:
CacheManager
问题是在作为测试套件的一部分刷新上下文时发生的,我认为这是在public Cache<T, V> initCache(String name, Class<T> type, Class<T> valueType) {
Cache<T, V> cache = manager.getCache(cacheName, keyType, valueType);
if (cache != null)
{
return cache;
}
cache = manager.createCache(cacheName, config);
return cache;
}
中完成的,因为我没有明确刷新上下文。发生以下错误,仅导致通过第一类测试:
AbstractTestNGSpringContextTests
看看发生了什么变化,我发现GenericWebApplicationContext: Refreshing org.springframework.web.context.support.GenericWebApplicationContext@6170989a
....
WARN GenericWebApplicationContext: Exception encountered during context initialization - cancelling refresh attempt
....
Factory method 'tokenStore' threw exception
nested exception is java.lang.IllegalStateException: Cannot overwrite a Cache's CacheManager.
抛出了一个AbstracthazelcastCacheManager
,它来自Hazelcast IllegalStateException
。更确切地说,CacheProxy
-> manager.getCache()
->在getCacheUnchecked()
->中创建一个缓存代理,并将代理的管理者设置为createCacheProxy()
中的当前管理者。
从Hazelcast v3.9开始,一旦设置了管理器,就不再允许使用此功能。
对此有什么解决方案?可能是Hazelcast中有一个错误(无法检查所设置的管理器是否实际上与现有管理器不同),但是我正在寻找可以自己做的事情。为什么'getCache()'尝试重新创建代理是我不明白的另一件事。
我认为我必须做一些事情,以确保不会刷新上下文,但是我不知道(如果有的话)我该怎么做。
答案 0 :(得分:0)
该问题是由于创建缓存管理器Bean的方式引起的。我使用了内部的Hazelcast缓存管理器,每次都创建一个新实例。像下面这样使用JCache API解决了问题
@Bean
public CacheManager cacheManager() {
HazelcastServerCachingProvider provider = Caching.getCachingProvider(); // or add class name of Hazelcast server caching provider to disambiguate
return provider.getCacheManager(null, null, HazelcastCachingProvider.propertiesByInstanceItself(HAZELCAST_INSTANCE));
}
从Hazelcast团队收到有关以下方面的帮助:https://github.com/hazelcast/hazelcast/issues/16212