问题
I have Spring 1.4 app which is deployed to WildFly 10, and it is using Infinispan 8.1 built in with WildFly.
I have managed to deploy the app properly, and this is the configuration for the 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
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-spring</artifactId>
<version>8.1.0.Final</version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-jcl</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
</exclusion>
</exclusions>
</dependency>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<archive>
<manifestEntries>
<Dependencies>org.infinispan, org.infinispan.commons, org.jboss.as.clustering.infinispan export</Dependencies>
</manifestEntries>
</archive>
</configuration>
</plugin>
When I deploy the app for the first time everything works fine. However, after the cache has been started, and when the application is redeployed I get the following error when using cache:
java.lang.ClassCastException: com.dplesa.Class cannot be cast to com.dplesa.Class
I tried this with different classes and no mater what I do, the error is the same. However, I don't get this error from caches where simple Strings are cached. What could cause this problem?
回答1:
This may sound scary but in this case, the behavior is correct.
A class is always binded to a particular classloader. Wildfly uses modular classloaders and each deployment uses different classloader instance. Now imagine that you put some instances of your class using classloader 'A', do redeployment (classloader 'A' is being disposed and new deployment is loaded using classloader 'B') and try to read data from cache using classloader 'B'. Those classloaders don't match and this results with your exception - Class com.dplesa.Class
cannot be cast to com.dplesa.Class
.
There are several ways to fix this:
Embed Infinispan with your application (using
infinispan-embedded
artifact for example). With this trick, Infinispan will be loaded with the same classloader as your domain classes.Put your domain classes in Wildfly modules.
Deploy Infinispan cluster separately and connect to it using HotRod Client (using
infinispan-remote
artifact for example).
Solution #1 is the simplest but you need to pay attention what's happening to your cluster during redeployments (make sure your nodes join/leave the cluster properly, that your data replicates as you desire etc).
来源:https://stackoverflow.com/questions/40584215/infinispan-with-spring-casting-from-cache-failing