WildFly集群MarshallableUserObject序列化异常解决问询
核心原因
负载均衡的健康检查请求触发了会话操作,但会话中存在未实现Serializable接口的对象,Infinispan用Protostream序列化时无法处理java.lang.Object这种非序列化类型,导致警告。
具体解决步骤
排查并修复会话中的非序列化对象
检查应用代码里所有往HttpSession存数据的地方,有没有直接存new Object()或者自定义未实现Serializable的类实例。比如代码里如果有session.setAttribute("temp", new Object());这种写法,要么把对象改成实现Serializable接口,要么换成可序列化的类型(比如用HashMap代替原生Object)。
要是找不到具体位置,加个HttpSessionListener,在attributeAdded方法里打印属性的类型,快速定位问题对象。调整Infinispan序列化配置(临时方案)
在standalone-ha.xml的web缓存容器里,给ProtostreamMarshaller配置白名单,允许特定类序列化:<cache-container name="web" default-cache="repl" module="org.wildfly.clustering.web.infinispan"> <transport lock-timeout="60000"/> <distributed-cache name="dist" mode="ASYNC" l1-lifespan="0" owners="2"> <serialization> <marshaller class="org.infinispan.commons.marshall.ProtostreamMarshaller"> <properties> <property name="java_serialization_whitelist" value="java.lang.Object,com.yourapp.**"/> </properties> </marshaller> <allow-list> <class>java.lang.Object</class> <class>com.yourapp.**</class> </allow-list> </serialization> </distributed-cache> </cache-container>注意:这个是临时 workaround,最好还是修复应用里的非序列化对象,不然可能隐藏其他序列化问题。
让健康检查请求不触发会话
把负载均衡健康检查的路径(比如/health)排除在会话跟踪外,在web.xml里添加配置:<session-config> <tracking-mode>COOKIE</tracking-mode> <exclude-url-pattern>/health</exclude-url-pattern> </session-config>这样健康检查请求不会创建或更新会话,从根源避免序列化操作。
升级WildFly版本
WildFly 25配套的Infinispan版本可能存在这个序列化bug,升级到WildFly 26或更高版本(对应Infinispan 14及以上),官方已经修复了MarshallableUserObject相关的序列化问题。
内容的提问来源于stack exchange,提问作者Richard

