启动层初始化报错:jdk.internal.jrtfs包同时存在于java.base与jrt.fs模块

问题根因
这是Java 9引入模块化系统(JPMS)后的典型拆分包冲突:模块化系统有强制约束,同路径的包只能归属一个已加载模块,一旦检测到两个模块包含相同包名的内容,会直接抛出启动层初始化错误,终止程序启动。
本次冲突的两个来源非常明确:
jdk.internal.jrtfs是JDK核心模块java.base自带的内部实现包,负责Java运行时镜像(jrt协议)的文件系统逻辑,JDK9及以上版本默认内置这套实现,不需要额外引入- 冲突的
jrt.fs模块来自独立发布的jrt文件系统组件,最常见的是适配JDK8及更早版本的jrt-fs.jar。旧版JDK没有内置jrt文件系统能力,需要单独引入这个包实现相关功能,高版本JDK环境下如果把这个jar放到模块路径加载,就会和内置实现产生包路径冲突。
常见触发场景:
- Maven/Gradle依赖传递引入了独立发布的jrt-fs组件
- IDE运行配置、启动脚本里手动把JDK目录下的兼容包
jrt-fs.jar加到了模块路径 - 用jlink打包自定义运行时镜像时,重复添加了jrt.fs模块
排查修复方案
按以下顺序排查,可覆盖绝大多数触发场景:
- 先确认运行环境的JDK版本,执行
java -version,如果是JDK9及以上版本,所有独立引入的jrt-fs组件都是冗余的,直接移除即可。 - 排查构建工具的依赖树:
- Maven项目执行
mvn dependency:tree,在输出中搜索jrt-fs、jrtfs关键词,定位到引入该依赖的上游组件,在对应依赖配置中添加排除规则,示例:<exclusion> <groupId>org.openjdk.jrtfs</groupId> <artifactId>jrt-fs</artifactId> </exclusion> - Gradle项目执行
gradle dependencies定位依赖来源,在对应依赖项中添加排除规则:exclude group: 'org.openjdk.jrtfs', module: 'jrt-fs'
- Maven项目执行
- 检查运行时配置:打开IDE的项目模块依赖设置、启动脚本的VM参数、类路径/模块路径配置,找到手动添加的
jrt-fs.jar条目直接删除。高版本JDK运行时不需要手动加载这个jar,手动追加反而会触发冲突。 - 如果是用jlink制作自定义运行时镜像的场景,检查打包命令的
--add-modules参数,删掉手动指定的jrt.fs模块,该模块的能力已经内置在java.base中,不需要额外添加。 - 有跨JDK版本兼容的特殊需求必须保留独立jrt-fs包的场景,不要把该jar放在模块路径加载,放到传统类路径下作为无名模块加载,即可绕过模块化系统的拆分包检查。
内容的提问来源于stack exchange,提问作者shubham jain
相关产品推荐
相关产品推荐

