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

使用Java 9模块解决Maven遗留代码JarHell问题遇阻

Java 9自动模块与遗留依赖冲突问题解答

一、自动模块的传递性

自动模块默认具备传递性。当非模块化Jar被声明为自动模块后,它会将自身依赖的所有Jar(即使是非模块化的)自动推断为依赖模块,JVM会尝试解析这些传递依赖。但问题在于,部分老依赖(如com.sun.xml.bind这类)本身没有模块描述符,当它们被自动模块依赖时,JVM无法自动识别对应的模块名,就会抛出找不到模块的错误。

二、遗留代码的处理方案

1. 显式添加缺失的自动模块依赖

针对报错中提到的com.sun.xml.txw2这类模块,直接将对应的Jar作为依赖引入到API模块中。这些Jar本身是非模块化的,JVM会自动将它们转为自动模块,从而被依赖它的模块识别。比如在Maven中添加:

<dependency>
    <groupId>com.sun.xml.txw2</groupId>
    <artifactId>txw2</artifactId>
    <version>匹配jrs-rest-java-client的对应版本</version>
</dependency>

可通过mvn dependency:tree命令查看依赖树,找到jrs-rest-java-client依赖的准确版本。

2. 用JVM参数补全依赖关系

在运行时通过JVM参数显式指定需要的模块及依赖关系:

  • --add-modules com.sun.xml.txw2:强制将该模块加入模块路径
  • --add-reads com.sun.xml.bind=com.sun.xml.txw2:允许com.sun.xml.bind模块读取com.sun.xml.txw2模块的内容

如果缺失模块较多,可使用--add-modules ALL-MODULE-PATH,让JVM加载模块路径上的所有自动模块,适合快速验证场景。

3. 回归依赖排除解决JarHell

放弃模块拆分,直接在Spring Boot项目中排除冲突依赖,保留jrs-rest-java-client需要的版本。比如若Spring与客户端的jaxb相关依赖版本冲突,可在Maven中排除Spring的对应依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-core</artifactId>
        </exclusion>
    </exclusions>
</dependency>

随后显式引入jrs-rest-java-client依赖的jaxb版本,保证依赖一致性。

4. 用maven-shade-plugin打包超级Jar

将API模块与所有依赖(含jrs-rest-java-client及其依赖)打包成一个带模块描述符的超级Jar,手动指定模块名和依赖关系,避免自动模块的推断问题。该方式配置稍复杂,适合需严格模块化的场景。

三、是否需要显式声明整个依赖栈?

不需要完整声明整个依赖栈,但需要显式声明JVM无法自动识别的依赖。自动模块会传递依赖,但对于无明确模块名的老Jar,JVM可能无法正确推断模块名,导致找不到模块。此时只需添加报错中提到的缺失模块对应的依赖即可,其他能被自动推断的依赖无需额外声明。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 16:50:23