Java模块系统下如何不导出与主代码同包的单元测试?
Java模块系统下Maven测试代码导出问题解决方案
可以将测试类排除在模块导出范围之外,不需要调整主模块的exports配置,通过以下方式即可解决报错:
核心原因
Java 9+模块系统默认将同一项目下的测试代码归属于主源码对应的模块下,你项目中测试依赖的wtf.g4s8.oot模块未在主module-info.java中声明,同时你开启了-Werror参数,所以模块检查的警告直接转为编译错误。
推荐方案(无侵入生产配置)
通过Maven编译插件的--patch-module参数,仅在测试编译阶段将测试代码合并到主模块中,不会修改生产环境的模块规则:
修改pom.xml中maven-compiler-plugin配置:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.11.0</version> <executions> <execution> <id>default-compile</id> <configuration> <release>17</release> <!-- 替换为实际使用的Java版本 --> </configuration> </execution> <execution> <id>default-testCompile</id> <configuration> <release>17</release> <compilerArgs> <!-- 将测试源码合并到主模块 --> <arg>--patch-module</arg> <arg>com.example=${project.build.testSourceDirectory}</arg> <!-- 给主模块添加测试依赖的读取权限 --> <arg>--add-reads</arg> <arg>com.example=wtf.g4s8.oot</arg> </compilerArgs> </configuration> </execution> </executions> </plugin>
该配置实现效果:
- 测试代码可正常访问主模块中
com.example包下的包私有类,符合你的测试需求 - 不需要在主
module-info.java中声明任何测试相关的依赖,不会污染生产配置 - 测试代码不会被纳入主模块的导出范围,打包生产jar时不会包含任何测试相关内容
替代方案
如果不想修改编译插件配置,可在src/test/java目录下新增module-info.test测试专属模块配置:
open module com.example.test { requires com.example; requires wtf.g4s8.oot; }
注意需使用3.8.0及以上版本的maven-compiler-plugin,才可自动识别该测试模块配置。
内容的提问来源于stack exchange,提问作者Kirill
相关产品推荐
相关产品推荐

