jdk11的项目在执行打包的时候,在编译阶段报了以下的错误:
FlinkConfigAspect.java:0::0 Type java.lang.Throwable is indirectly referenced from required .class files but cannot be resolved since the declaring package java.lang exported from module java.base conflicts with a package accessible from module <unnamed>
由于我的项目是jdk11的版本,依赖的三方的jar中定义了moudle-info.java的模块配置信息,
Java 9 开始有了模块化系统的概念(JPMS), 每个Java 文件都属于某个模块. 例如上面例子中出现的 java.util.Throwable都属于JDK里面的 java.base 模块。
那么<unnamed> 模块是什么呢?
对于JDK本身, 它默认已经分了模块, 但是我们还有很多jar包, 并没有按照模块的方式去打包, 或者在JDK 9 之前就有了这些jar包, 我们照样可以依赖它们.
对各种模块的依赖, 会加到modulepath, 对于非模块的依赖, 继续使用classpath. classpath上的类会被统一的分配到一个叫<unnamed>的模块.
错误含义
所以, 这个错误的真正含义是: 在我们依赖中, java.lang包即出现在了 JDK 的 java.base 这个模块, 也出现在了我们依赖的classpath上. 而Java模块化系统不允许同一个包出现在2个模块里面。
排查结果:
经过排查最后发现引入的三方依赖中,自己定义java.lang包名:

总结:
即使第三方依赖没有定义 Throwable 类,只要它包含了 java.lang 包路径,就极有可能导致模块系统冲突。这是因为:
-
模块系统基于包名而不是特定类检测冲突
-
java.lang是 Java 平台保留的特殊包名 -
任何非
java.base模块包含java.lang包都会导致包分裂问题
- 模块系统冲突的核心机制是"包分裂"(Split Package)问题,而不是特定类的存在:
- 包名冲突:模块系统不允许同一个包名出现在多个模块中
- java.lang 的特殊性:
java.lang是 Java 平台的核心包,由java.base模块独占 - 自动模块命名:即使第三方依赖没有
module-info.java,当放在模块路径上时,它会被视为"自动模块"
解决方案的优先顺序应该是:
1.修复或替换问题依赖(最佳方案)
2.使用 Shade 插件重命名问题包
如果无法替换依赖,使用 Shade 插件重命名其中的非法包:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<relocations>
<relocation>
<pattern>java.lang</pattern>
<shadedPattern>shaded.javalang</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
3.确保问题依赖在类路径而非模块路径上
通过配置确保问题依赖在类路径上加载,而不是模块路径:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<compilerArgs>
<!-- 明确指定模块路径,确保问题依赖不在其中 -->
<arg>--module-path</arg>
<arg>${project.build.directory}/modules</arg>
<arg>--class-path</arg>
<arg>${project.build.directory}/classes:${project.build.directory}/dependency/*</arg>
</compilerArgs>
</configuration>
</plugin>
</plugins>
</build>
4.尝试使用模块系统参数
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<compilerArgs>
<arg>--add-modules</arg>
<arg>ALL-MODULE-PATH</arg>
<arg>--add-opens</arg>
<arg>java.base/java.lang=ALL-UNNAMED</arg>
<!-- 尝试隐藏问题模块 -->
<arg>--patch-module</arg>
<arg>java.base=</arg>
</compilerArgs>
</configuration>
</plugin>
参考:
1669

被折叠的 条评论
为什么被折叠?



