Liferay DXP迁移Tomcat环境下Stax Provider子类型错误排查
XMLInputFactory服务配置错误的具体方向 遇到这个ServiceConfigurationError确实挺头疼的,尤其是在跨Liferay版本和应用服务器迁移的时候。这个错误的核心原因是JVM加载XMLInputFactory实现类时,发现它和当前加载的XMLInputFactory接口不属于同一个类定义——要么是被不同类加载器加载,要么是API版本不匹配导致类结构不一致。结合你已经做的排查,我给你几个更具体的排查方向:
确认
XMLInputFactory接口的加载来源
这个问题大概率是类加载器冲突导致的:JDK 8自带的XMLInputFactory由系统类加载器加载,而war包中geronimo-stax-api里的同名接口由web应用类加载器加载,两者虽然类名相同,但属于不同的类对象。你可以通过两种方式验证:- 在代码中添加调试逻辑,打印类加载器信息:
如果输出的类加载器不同,那就是类加载隔离导致的冲突。System.out.println("XMLInputFactory class loader: " + XMLInputFactory.class.getClassLoader()); System.out.println("WstxInputFactory class loader: " + com.ctc.wstx.stax.WstxInputFactory.class.getClassLoader()); - 用
java -verbose:class参数启动应用,搜索javax.xml.stream.XMLInputFactory的加载记录,看它是从JDK的rt.jar加载,还是从war包内的geronimo-stax-api jar加载。
- 在代码中添加调试逻辑,打印类加载器信息:
排除冗余的Stax API依赖
JDK 6及以上版本已经自带了Stax API实现,war包中不需要再引入额外的Stax API依赖(比如geronimo-stax-api)。你可以通过Gradle依赖树确认它的来源,然后在构建脚本中排除:implementation('org.apache.axis2:axis2-adb:1.6.3') { // 排除传递引入的Stax API依赖 exclude group: 'org.apache.geronimo.specs', module: 'geronimo-stax-api_1.0_spec' }排除后重新构建war包,看错误是否消失。
验证Woodstox版本与JDK 8的兼容性
你使用的woodstox-core-asl-4.1.4是比较老旧的版本,可能和JDK 8自带的Stax API存在兼容性问题。旧版本的Woodstox可能是基于更早的Stax API规范编译的,导致它的WstxInputFactory无法被JDK 8的XMLInputFactory接口识别为子类。可以尝试升级Woodstox到兼容JDK 8的版本(比如5.x系列),同时确保只保留Woodstox的实现jar,不要引入任何Stax API依赖。检查Liferay DXP的类加载器隔离配置
Liferay有自己的类加载器隔离机制,可能影响Stax相关类的加载:- 如果你的Portlet是传统插件形式,检查
liferay-plugin-package.properties中的配置,比如system.packages.extra是否错误地引入了Stax相关包,导致类加载混乱。 - 如果是OSGi模块,检查
bnd.bnd中的Import-Package或Private-Package设置,确保Stax相关包的导入配置正确。 - 同时可以检查Liferay全局类加载器的jar包(比如
tomcat/webapps/ROOT/WEB-INF/lib目录),确认是否有其他Stax相关依赖可能导致冲突。
- 如果你的Portlet是传统插件形式,检查
构建最小化测试场景
把问题简化:创建一个只包含axis2-adb依赖和简单WebService调用逻辑的测试Portlet,排除原Portlet中的其他依赖。如果测试场景正常,再逐步添加原Portlet的依赖,这样能快速定位到导致冲突的具体依赖项。
内容的提问来源于stack exchange,提问作者Sandeep Nair

