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

JPMS运行时如何确定根模块以构建模块图

JPMS运行时模块图构建的根模块确定规则

你之前的认知存在两处初学者常见偏差,以下是完整的规则说明:

默认根模块集合的判定

默认情况下模块路径上的所有模块并不会被全部加入根模块集合,根模块的默认范围和启动方式直接相关:

  • 启动模块化应用时(通过java --module <初始模块>/<主类全限定名>命令启动):只有命令行指定的初始模块会被加入默认根模块集合
  • 启动非模块化应用时(主类从类路径加载):只有核心基础模块java.base会被加入默认根模块集合,其余JDK内置模块、模块路径上的自定义模块都不会默认进入根集合

自定义根模块集合的方式

你提到的--add-modules参数是修改根模块集合的核心方式,它除了支持指定具体模块名,还有几个常用特殊值:

  • --add-modules <模块1>,<模块2>:将列出的显式模块直接加入根模块集合
  • --add-modules ALL-MODULE-PATH:将模块路径上所有可观测的模块全部加入根模块集合,这也是你之前认知里“模块路径模块全进根集合”的场景,属于参数显式指定的行为而非默认逻辑
  • --add-modules ALL-SYSTEM:将所有JDK内置的系统模块加入根模块集合
  • --add-modules ALL-DEFAULT:将JDK默认隐式加载的系统模块集合加入根,常用于注解处理、编译插件类场景

模块图构建与类路径回退逻辑

确定根模块集合后,JPMS会递归解析所有根模块在module-info.java中声明的requires依赖,把整条依赖链上的模块都加入模块图,没有被依赖链覆盖到的模块,哪怕放在模块路径上也不会被加载进模块图。
关于类加载和未命名模块的逻辑,你之前的理解基本准确,补充两个细节:

  • 只有当模块图内所有已解析模块都找不到目标类时,JPMS才会回退到类路径搜索
  • 类路径下加载到的所有类都归属于全局唯一的未命名模块,这个模块不需要手动声明,默认拥有读取所有已解析命名模块的权限;未命名模块本身不会自动进入根模块集合,只有实际触发类路径上的类加载时,对应类才会被加载到未命名模块中。

常见踩坑:很多初学者把第三方模块放到模块路径后依然报ClassNotFoundException,本质原因就是这些模块既没有被初始模块requires声明依赖,也没有通过--add-modules加入根集合,压根没有被解析进模块图。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 02:06:33