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

Java9模块化JavaFX应用JUnit5测试遇ResolutionException问题求助

问题原因分析

这个冲突只在测试时出现,核心原因是运行时和测试时的模块路径组成不一样:

  • 主应用运行(run任务)时,依赖的模块集合里没有触发冲突的组合——要么是commons-logging这类依赖只被测试路径间接引入,要么主应用的模块路径过滤掉了冲突的自动模块。
  • 测试运行时,JUnit相关依赖会间接引入commons-logging,同时你的主依赖odfdom-java会拉进来xercesImpl(一个自动模块),而JDK自带的jdk.xml.dom模块也导出org.w3c.dom.html包。当模块系统尝试解析时,发现两个模块(xercesImpl和jdk.xml.dom)都向commons-logging导出同一个包,违反了Java模块系统的唯一性规则,所以抛出ResolutionException。
解决方案

下面提供几种可行的解决思路,按优先级尝试:

1. 排除冗余的xercesImpl依赖

JDK自带的jdk.xml.dom已经提供了org.w3c.dom.html相关的实现,xercesImpl属于冗余依赖,可以从odfdom-java中排除它:
修改build.gradle的依赖配置:

implementation('org.odftoolkit:odfdom-java:0.12.0') {
    exclude group: 'xerces', module: 'xercesImpl'
}

这样测试路径里就不会同时存在两个导出相同包的模块,冲突自然消失。

2. 将冲突依赖移到类路径而非模块路径

如果排除xercesImpl后导致主应用运行异常(比如odfdom-java确实需要它的某些特性),可以把xercesImpl或者commons-logging标记为“非模块”,让它们在类路径运行(而非模块路径):
在build.gradle中添加测试任务的配置:

tasks.named('test', Test) {
    useJUnitPlatform()
    // 精确过滤模块路径,移除冲突的xercesImpl
    modularity.modulePath = sourceSets.test.runtimeClasspath.filter { !it.name.contains('xercesImpl') }
    // 将xercesImpl加入类路径
    classpath += sourceSets.test.runtimeClasspath.filter { it.name.contains('xercesImpl') }
}

这种方式既能保留其他依赖的模块化特性,又能规避冲突。

3. 调整模块声明(module-info.java)

如果你的主模块是显式模块,可以在module-info.java中明确指定依赖JDK的jdk.xml.dom模块,强制使用它的org.w3c.dom.html包:

module your.module.name {
    requires jdk.xml.dom;
    // 其他模块依赖声明...
}

配合上面的依赖排除或类路径配置一起使用,能进一步强化模块解析的优先级。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 21:58:36