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

为何ServiceLoader.load(...)运行正常但Maven测试失败?

问题解决:Maven测试时ServiceLoader无法找到JPMS提供的实现

核心原因

Maven Surefire插件默认可能未启用**模块路径(Module Path)**模式,导致测试时忽略了module-info.java中的uses/provides声明,转而用传统类路径方式运行,使得JPMS的服务发现机制失效。而IDE会自动处理模块上下文,所以运行正常。

解决方案

1. 升级并配置Surefire插件

确保使用支持JPMS的最新版Surefire插件,并强制启用模块路径:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>3.2.5</version> <!-- 推荐使用最新稳定版 -->
            <configuration>
                <!-- 强制使用模块路径运行测试 -->
                <useModulePath>true</useModulePath>
                <!-- 测试时临时导出内部包给web模块(如果测试代码需要访问的话) -->
                <addModuleExports>
                    <addModuleExport>com.sample.domain/com.sample.domain.internal=com.sample.web</addModuleExport>
                </addModuleExports>
            </configuration>
        </plugin>
    </plugins>
</build>

2. 验证测试模块的声明

如果你的测试代码有独立的module-info.test.java,需要确保它包含:

module com.sample.web.test {
    requires com.sample.domain;
    uses com.sample.domain.api.UseCase;
    // 其他测试相关依赖
}

如果是使用open module,也要保证测试模块的配置兼容。

3. 确认模块依赖的正确性

在com.sample.web的pom.xml中,确保com.sample.domain的依赖是模块依赖而非普通JAR依赖:

<dependency>
    <groupId>com.sample</groupId>
    <artifactId>domain</artifactId>
    <version>${project.version}</version>
</dependency>

4. 备选:显式指定ServiceLoader的模块上下文

如果上述配置仍有问题,可以在测试代码中显式指定模块层:

@Bean
UseCase useCase() {
    // 显式使用启动模块层来加载服务
    return ServiceLoader.load(ModuleLayer.boot(), UseCase.class)
                       .findFirst()
                       .orElseThrow();
}

内容的提问来源于stack exchange,提问作者energize-cactus

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 12:32:46