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

Java模块能否参照子域名形式分层定义?SPI报错如何解决

Java模块分层命名与SPI报错问题解答

分层模块命名可行性

你提到的类似子域名的分层Java模块命名方式是完全合法的。JPMS(Java平台模块系统)对模块名没有“必须对应完全独立代码单元”的强制要求,com.acme.transport、com.acme.transport.water、com.acme.transport.air这类命名符合Java模块命名规范,仅作为模块的唯一标识使用。
需要明确的是:命名上的层级从属关系不会被JPMS自动识别,不存在“父模块自动继承子模块配置、子模块自动获得父模块权限”的规则,所有模块依赖、SPI声明、包导出/开放配置都必须在每个模块的module-info.java中显式定义。

SPI报错根因

你遇到的java.util.ServiceConfigurationError本质是违反了JPMS的SPI校验规则:

JPMS规定,调用ServiceLoader.load()加载服务的模块,必须在自身的module-info.java中声明对应服务类型的uses指令,该声明不会跨模块传递,和服务接口定义在哪个模块、其他模块有没有声明过uses没有关系。

从错误栈可以看出,加载SelectQueryProvider的调用逻辑实际位于jakarta.nosql.communication.core模块中,但你只在jakarta.nosql.communication.query模块里声明了对应SPI的uses,core模块既没有依赖query模块,也没有声明对应服务的uses,因此触发运行时校验错误。

修复方案

你可以根据代码实际架构选择其中一种方案修复:

  • 如果core模块确实需要直接加载query模块定义的SPI:
    • 在jakarta.nosql.communication.core的module-info.java中添加requires jakarta.nosql.communication.query;依赖,保证core模块可以访问到query模块导出的SPI接口;
    • 补充所有core需要加载的、来自query模块的SPI服务的uses声明。
  • 如果query是core的独立扩展模块(更符合分层逻辑):
    • 将所有query模块专属SPI的ServiceLoader加载逻辑,从core模块移到jakarta.nosql.communication.query模块内部实现;
    • 保证声明uses指令的模块和实际调用ServiceLoader加载服务的模块是同一个,无需修改core模块的配置。

内容的提问来源于stack exchange,提问作者Otávio Santana

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 12:03:18