You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Wildfly部署时Infinispan缓存序列化误用过时DOMSerializerImpl问题

问题:向Infinispan缓存存入对象时出现序列化错误

报错详情

存入缓存时触发以下错误:

ISPN000559: Cannot marshall 'class org.infinispan.marshall.protostream.impl.MarshallableUserObject': org.w3c.dom.ls.LSException

堆栈信息显示程序调用了过时的org.apache.xerces@2.12.0.SP03//org.apache.xml.serialize.DOMSerializerImpl.writeToString(DOMSerializerImpl.java:518)类,而预期应使用xalan serializer 2.7.2。

代码逻辑背景

应用内直接执行序列化时可正常使用正确的序列化器,逻辑来自xercesImpl-2.12.2的CoreDomImplementationImpl.java:

public LSSerializer createLSSerializer() {
        try {
            Class serializerClass = ObjectFactory.findProviderClass(
                "org.apache.xml.serializer.dom3.LSSerializerImpl",
                ObjectFactory.findClassLoader(), true);
            return (LSSerializer) serializerClass.newInstance();
        }
        catch (Exception e) {}
        // Fall back to Xerces' deprecated serializer if 
        // the Xalan based serializer is unavailable.
        return new DOMSerializerImpl();
    }

业务侧的序列化调用代码:

public static @Null
String documentToString(@Null Document document) {
    if (document == null) {
        return null;
    }
    DOMImplementationLS domImplementation = (DOMImplementationLS) document.getImplementation();
    LSSerializer lsSerializer = domImplementation.createLSSerializer();

    String result = lsSerializer.writeToString(document);
  
    return result;
}

环境配置:WEB-INF/lib已包含xalan-2.7.2,使用Wildfly 26.1.2.Final、Infinispan 13.0.10.Final。

原因分析

  1. 容器类加载器优先级冲突:Wildfly容器自带了xerces 2.12.0.SP03,容器类加载器的优先级高于应用WEB-INF/lib的类加载器,导致org.apache.xml.serializer.dom3.LSSerializerImpl无法被加载,触发了代码中的降级逻辑,转而使用过时的DOMSerializerImpl。
  2. Infinispan序列化上下文差异:存入Infinispan缓存时,序列化操作是在Infinispan的类加载器上下文中执行的,而非应用自身的类加载器,此时无法找到WEB-INF/lib中的xalan序列化器类,最终触发fallback逻辑。

修复方案

方案1:调整Wildfly类加载优先级

在应用的jboss-deployment-structure.xml中配置,让应用优先加载自身WEB-INF/lib中的xerces和xalan相关类,避免容器类覆盖:

<jboss-deployment-structure>
    <deployment>
        <exclusions>
            <!-- 排除容器自带的xerces和xalan模块 -->
            <module name="org.apache.xerces"/>
            <module name="org.apache.xalan"/>
        </exclusions>
        <dependencies>
            <!-- 可选:如果需要依赖容器模块时使用应用类 -->
            <module name="org.apache.xerces" export="true" optional="true"/>
            <module name="org.apache.xalan" export="true" optional="true"/>
        </dependencies>
    </deployment>
</jboss-deployment-structure>

方案2:显式指定序列化器类

绕过自动查找逻辑,直接在代码中实例化xalan的序列化器,避免fallback到过时实现:

public static @Null String documentToString(@Null Document document) {
    if (document == null) {
        return null;
    }
    LSSerializer lsSerializer;
    try {
        // 直接加载xalan的LSSerializer实现类
        Class<?> serializerClass = Class.forName("org.apache.xml.serializer.dom3.LSSerializerImpl");
        lsSerializer = (LSSerializer) serializerClass.newInstance();
    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
        // 降级到原有逻辑作为兜底
        DOMImplementationLS domImplementation = (DOMImplementationLS) document.getImplementation();
        lsSerializer = domImplementation.createLSSerializer();
    }
    return lsSerializer.writeToString(document);
}

方案3:验证依赖完整性

确认构建脚本(如pom.xml)中xalan依赖的scope为compile,且没有被其他依赖排除;同时检查WEB-INF/lib中是否同时存在xalan-2.7.2.jar和对应的serializer-2.7.2.jar(xalan序列化器依赖该组件)。

内容的提问来源于stack exchange,提问作者Victoria

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 18:30:41