Infinispan 8升级到12后HashMap等Java原生类型序列化报错如何解决
问题根因
- Infinispan 11+版本默认移除了对Java原生序列化的默认支持,默认采用ProtoStream作为序列化框架,仅支持内置白名单的类型,HashMap等原生JDK类型不在默认白名单中所以抛出序列化异常。
- 你遇到的类转换异常是类加载器隔离冲突:你的EAR包自己加载了
JavaSerializationMarshaller类,而Infinispan公共模块的Marshaller接口是由服务器的模块类加载器加载的,两个类来自不同类加载器因此无法转换。
最简修复方案
第一步:解决类加载冲突
如果是部署在WildFly/JBoss EAP类的应用服务器,在你的EAR包的META-INF/jboss-deployment-structure.xml中添加Infinispan公共模块的依赖,避免应用重复加载序列化相关类:
<jboss-deployment-structure> <deployment> <dependencies> <module name="org.infinispan.commons" export="true" /> </dependencies> </deployment> </jboss-deployment-structure>
第二步:配置Java序列化Marshaller
在Infinispan的xml配置文件中,显式指定使用Java序列化Marshaller,同时添加你需要序列化的JDK类型白名单:
<infinispan> <cache-container default-cache="default"> <serialization marshaller="org.infinispan.commons.marshall.JavaSerializationMarshaller"> <white-list> <!-- 可单独添加需要的类 --> <class>java.util.HashMap</class> <class>java.util.ArrayList</class> <!-- 也可以用正则一次性匹配所有java.util下的类 --> <regex>java\.util\..*</regex> <!-- 自定义的序列化类也需要加在这里 --> </white-list> </serialization> <!-- 保留你原有的其他缓存配置 --> </cache-container> </infinispan>
可选替代方案:编程式配置
如果你是通过代码初始化缓存容器,可以直接指定marshaller,避免xml配置加载问题:
GlobalConfiguration globalConfig = new GlobalConfigurationBuilder() .serialization() .marshaller(new JavaSerializationMarshaller()) .whiteList() // 添加需要序列化的类的匹配规则 .addRegexps("java.util.*", "com.yourbusinesspackage.*") .build(); DefaultCacheManager cacheManager = new DefaultCacheManager(globalConfig);
注意事项
- Java原生序列化本身存在安全性风险,如果你的缓存数据只在内部可信环境使用,上述方案完全满足需求,如果有外部访问的场景建议后续改用官方推荐的ProtoStream序列化。
- 所有需要序列化的自定义业务类也需要添加到白名单中,否则还是会抛出序列化异常。
内容的提问来源于stack exchange,提问作者Lluc
相关产品推荐
相关产品推荐

