Infinispan with Spring, casting from cache failing

怎甘沉沦 提交于 2019-12-23 05:16:15

问题


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:

  1. 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.

  2. Put your domain classes in Wildfly modules.

  3. 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!