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

Java 8迁移至Java 10时Mockito 2.20.0模块可访问性问题求助

解决Java 10 JPMS下Mockito访问包私有/未导出类的测试失败问题

你遇到的问题本质是Java模块系统(JPMS)的访问控制机制和Mockito的反射需求之间的冲突:在Java 8中,包私有类或未导出的公共类可以通过反射轻松访问,但JPMS严格限制了跨模块的反射访问,而Mockito因为放在类路径下,被识别为unnamed module,自然无法访问模块内未开放的包。

下面是几个符合你需求(保持类对其他模块不可见)的解决方案:

1. 用--add-opens运行时参数开放反射访问

这是最直接的解决方案,不需要修改代码结构,仅在测试阶段开放所需包的反射权限给未命名模块(包含Mockito)。

修改maven-surefire-plugin的配置,添加JVM参数:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.22.0</version>
    <configuration>
        <argLine>
            <!-- 针对你测试的场景,开放对应的包给所有未命名模块 -->
            --add-opens nodatafound.mockito_jpms_usecase/nodatafound.mjpmsuc.withopens=ALL-UNNAMED
            --add-opens nodatafound.mockito_jpms_usecase/nodatafound.mjpmsuc.internal=ALL-UNNAMED
            <!-- 其他需要测试的包同理添加 -->
        </argLine>
    </configuration>
</plugin>
  • 原理:--add-opens是JPMS提供的运行时参数,允许指定模块的某个包对目标模块开放反射访问权限,但不会导出该包(导出会让其他模块都能正常访问,不符合你“保持不可见”的要求)。ALL-UNNAMED表示所有类路径下的未命名模块,正好覆盖你的Mockito。

2. 在module-info.java中声明包开放给Mockito

如果你的Mockito已经是自动模块(你提到它有Automatic-Module-Name),可以直接在模块描述符里指定开放特定包给Mockito,这样不需要依赖运行时参数:

module nodatafound.mockito_jpms_usecase {
    // 仅开放给Mockito模块,其他模块无法访问
    opens nodatafound.mjpmsuc.withopens to org.mockito;
    opens nodatafound.mjpmsuc.internal to org.mockito;
}
  • 注意:如果你的maven-surefire插件还是把Mockito放在类路径(而非模块路径),这个配置可能不生效——因为类路径下的Jar会被视为unnamed module,而不是org.mockito模块。这种情况下还是需要用方案1。

3. 升级Mockito和插件版本

你当前使用的Mockito 2.20.0对JPMS的支持还比较初期,建议升级到Mockito 3.x及以上版本(比如3.11.2),这些版本对JPMS的兼容性更好,包括对自动模块的识别、反射访问的优化。

同时,建议升级maven-surefire-plugin到3.0.0-M7及以上,新版插件对JPMS测试的支持更完善,能更好地处理模块路径和类路径的混合场景。

4. 调整类的访问级别(可选)

如果不想依赖反射开放参数,可以把包私有类改为public但放在未导出的包中——这样其他模块因为无法访问未导出的包,依然看不到这些类,而你可以通过opens或--add-opens让Mockito访问它们,效果和原来的包私有类一致。

另外,如果测试代码和被测试类在同一个模块的测试源目录(比如src/test/java),同一个模块内的测试代码默认可以访问包私有类,不需要额外配置——但这个方案只适用于模块内测试。


总结一下:最推荐的是方案1(--add-opens参数),它既满足你“保持类对其他模块不可见”的需求,又不需要修改代码结构,适配你当前的插件版本。如果后续升级了Mockito和插件,再考虑方案2或4。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:58:06