Infinispan with Spring,从缓存中转换失败

我有部署到WildFly 10的Spring 1.4应用程序,它使用的是WildFly内置的Infinispan 8.1。

我已经设法正确部署了应用程序,这是Infinispan的配置:1)CacheManager

@Bean public CacheManager cacheManager() throws Exception { JndiTemplate jndiTemplate = new JndiTemplate(); EmbeddedCacheManager embededCacheManager = (EmbeddedCacheManager) jndiTemplate.lookup("java:jboss/infinispan/container/CONTAINER"); SpringEmbeddedCacheManager cacheManager = new SpringEmbeddedCacheManager(embededCacheManager); } 

2)pom.xml

  org.infinispan infinispan-spring 8.1.0.Final   org.springframework.boot spring-boot-starter-logging   javax.servlet servlet-api   org.apache.logging.log4j log4j-core   org.apache.logging.log4j log4j-jcl   org.apache.logging.log4j log4j-slf4j-impl     org.apache.maven.plugins maven-war-plugin    org.infinispan, org.infinispan.commons, org.jboss.as.clustering.infinispan export     

当我第一次部署应用程序时,一切正常。 但是,在启动缓存后,以及重新部署应用程序时,使用缓存时出现以下错误:

 java.lang.ClassCastException: com.dplesa.Class cannot be cast to com.dplesa.Class 

我尝试了不同的类,不管我做什么,错误是一样的。 但是,我没有从缓存简单字符串的缓存中得到此错误。 什么可能导致这个问题?

这可能听起来很可怕,但在这种情况下,行为是正确的。

类始终绑定到特定的类加载器。 Wildfly使用模块化类加载器,每个部署使用不同的类加载器实例。 现在假设您使用类加载器’A’放置了类的一些实例,进行重新部署(使用类加载器’B’处理类加载器’A’并使用类加载器’B’加载新部署)并尝试使用类加载器’B’从缓存中读取数据。 这些类加载器不匹配,这会导致exception – 类com.dplesa.Class无法转换为com.dplesa.Class

有几种方法可以解决这个问题:

  1. 将Infinispan嵌入您的应用程序(例如使用infinispan-embedded工件)。 有了这个技巧,Infinispan将加载与您的域类相同的类加载器。

  2. 将您的域类放在Wildfly模块中。

  3. 单独部署Infinispan集群并使用HotRod Client连接到它(例如,使用infinispan-remote工件)。

解决方案#1是最简单的,但您需要注意重新部署期间群集发生的情况(确保您的节点正确加入/离开群集,您的数据可以根据需要进行复制等)。