Java模块系统下xercesImpl与jdk.xml.dom拆分包问题求助
解决Java模块系统中Xerces的拆分包冲突问题
问题背景
项目中引入了以下Maven依赖:
<dependency> <groupId>xerces</groupId> <artifactId>xercesImpl</artifactId> <version>2.12.2</version> <exclusions> <exclusion> <groupId>xml-apis</groupId> <artifactId>xml-apis</artifactId> </exclusion> </exclusions> </dependency>
同时配置了module-info.java:
open module de.powerstat.fb.mini { exports de.powerstat.fb.mini; requires transitive java.xml; requires org.apache.logging.log4j; requires transitive de.powerstat.validation; requires transitive org.apache.httpcomponents.httpclient; requires org.apache.httpcomponents.httpcore; requires org.apache.commons.codec; requires com.github.spotbugs.annotations; requires org.junit.jupiter.api; requires org.junit.jupiter.params; requires org.junit.platform.launcher; requires org.junit.platform.suite.api; }
运行测试时出现启动层初始化错误,dump文件显示核心问题:
java.lang.module.ResolutionException: Modules jdk.xml.dom and xercesImpl export package org.w3c.dom.html to module io.cucumber.core.gherkin.messages
原因是jdk.xml.dom和xercesImpl-2.12.2.jar都包含并导出了org.w3c.dom.html包,违反了Java模块系统(JPMS)不允许同一包被多个模块导出的规则。
解决方案
1. Xerces能否在Java模块系统中使用?
可以,但需要调整使用方式:
- 移除不必要的Xerces依赖:如果项目只是使用标准XML API(如DOM、SAX),完全可以依赖JDK自带的
java.xml模块实现,直接删除Xerces依赖即可,这是最省心的方案。 - 通过JVM参数解决冲突:如果必须保留Xerces,可通过
--patch-module参数将Xerces的冲突包合并到系统模块中。在Maven Surefire插件中添加以下配置:
这样Xerces的<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>3.5.0</version> <configuration> <argLine>--patch-module jdk.xml.dom=${settings.localRepository}/xerces/xercesImpl/2.12.2/xercesImpl-2.12.2.jar</argLine> </configuration> </plugin>org.w3c.dom.html包会被合并到jdk.xml.dom模块中,避免拆分包冲突。 - 使用模块化的Xerces版本:检查Xerces最新版本(如2.13.x及以后),部分新版本已适配JPMS,调整了包结构避免与JDK系统模块冲突。
2. Saxon能否作为替代方案?
Saxon主要是XSLT和XQuery处理器,如果你的项目仅需要基础XML解析、DOM操作,Saxon并非最佳替代——JDK自带的java.xml模块已经足够。但如果项目用到XSLT 2.0+/XQuery等高级功能,Saxon是优秀的选择,且它完全兼容JPMS,不会出现拆分包问题。
3. 其他解决办法
- 调整依赖范围:如果Xerces仅用于编译阶段,运行时用JDK实现,可将依赖的
scope设为compileOnly:<dependency> <groupId>xerces</groupId> <artifactId>xercesImpl</artifactId> <version>2.12.2</version> <scope>compileOnly</scope> <exclusions> <exclusion> <groupId>xml-apis</groupId> <artifactId>xml-apis</artifactId> </exclusion> </exclusions> </dependency> - 禁用JPMS自动模块处理:将Xerces放在类路径而非模块路径(通过Maven配置
maven.compiler.modulepath排除Xerces),但这种方法会弱化模块系统的优势,仅作为临时 workaround。
内容的提问来源于stack exchange,提问作者PowerStat
相关产品推荐
相关产品推荐

