如何解决JDK8升级至JDK11后javax.xml.namespace多模块可访问问题
这个问题我之前帮好几个升级JDK的开发者解决过,核心是JDK9开始引入的模块化系统和旧项目依赖之间的冲突导致的,我给你拆解下原因和具体解决步骤:
问题根源
在JDK8时代,javax.xml.namespace这类XML相关的包是放在rt.jar这个全局类库中的;但从JDK9开始,Java引入了模块化系统,把这些核心包拆分到了java.xml系统模块里。
如果你的项目升级到JDK11后,仍然依赖了像jaxb-api、javax.xml.bind:jaxb-api这类第三方库,就会出现冲突——因为模块化系统检测到javax.xml.namespace这个包既来自JDK自带的java.xml模块,又来自类路径上的第三方jar包,所以抛出了"accessible from more than one module"的错误。
具体解决方法
优先移除重复的第三方依赖
先检查你的依赖管理文件(Maven的pom.xml或Gradle的build.gradle),看看有没有引入包含javax.xml.namespace的第三方依赖(最常见的就是jaxb-api)。因为JDK11的java.xml模块已经包含了这个包的实现,直接移除这类依赖就能解决问题。- Maven示例:删掉对应的
<dependency>块 - Gradle示例:删掉
implementation 'javax.xml.bind:jaxb-api:x.x.x'这类声明
- Maven示例:删掉对应的
必须保留依赖时,排除冲突模块
如果项目确实需要某个第三方库,但它附带了冲突的包,可以在依赖声明里排除掉引发冲突的模块:- Maven配置示例:
<dependency> <groupId>你的依赖组ID</groupId> <artifactId>你的依赖ArtifactID</artifactId> <version>依赖版本</version> <exclusions> <exclusion> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> </exclusion> </exclusions> </dependency> - Gradle配置示例:
implementation('你的依赖组ID:你的依赖ArtifactID:依赖版本') { exclude group: 'javax.xml.bind', module: 'jaxb-api' }
- Maven配置示例:
模块化项目的特殊处理
如果你的项目是模块化项目(存在module-info.java),可以在文件里明确声明对java.xml模块的依赖,让模块化系统优先使用JDK自带的模块:requires java.xml;注意:不推荐使用
--patch-module参数作为长期方案,除非是临时兼容旧代码,因为这会破坏模块化系统的封装性。清理IDE缓存
有时候IDE会缓存旧的依赖或模块配置,导致修改后仍然报错。可以尝试:- IntelliJ IDEA:
File -> Invalidate Caches / Restart - Eclipse:
Project -> Clean
- IntelliJ IDEA:
内容的提问来源于stack exchange,提问作者amira

