根模块是模块系统启动和依赖解析的起点,不被其他模块依赖,由运行时环境主动加载;它触发递归解析、决定可见性边界、约束服务发现范围,并影响类加载委托链。

根模块是整个模块系统启动和依赖解析的起点,它不被任何其他模块声明为依赖,而是由运行时环境(如 JVM 或框架)主动加载并作为依赖树的顶层节点。
根模块的识别方式
在 Java 平台模块系统(JPMS)中,根模块通常由启动命令显式指定,例如使用 --module 参数:
-
java --module my.app/com.example.Main:此时
my.app就是根模块 - 若用 java -jar app.jar 启动,且 JAR 包含合法的
module-info.class,该模块自动成为根模块 - 在模块路径(--module-path)中,未被其他模块
requires的模块也可能被提升为隐式根模块(需满足可启动性条件)
它在依赖树生命周期中的核心作用
根模块不是被动参与者,而是驱动整个模块解析过程的“发起者”:
-
触发递归解析:JVM 从根模块的
module-info.class读取所有requires声明,逐层加载其直接依赖,再递归处理依赖的依赖,最终构建出完整的闭包(resolved module graph) -
决定可见性边界:只有被根模块显式或间接
requires的模块,才会进入运行时模块图;未被触及的模块即使存在于模块路径中,也不会被加载或链接 -
约束服务发现范围:通过
uses声明的服务接口,仅在根模块闭包内查找对应provides实现;超出闭包的服务不可见 -
影响类加载委托链:根模块的类加载器(通常是
Layer.ModuleLayer的启动层)成为整个模块图的委托起点,控制跨模块类访问的权限与路径
与普通模块的本质区别
根模块的特殊性不在语法上,而在语义和运行时角色:
- 语法上它和其他模块一样写
module my.app { requires java.base; exports com.example; } - 但它没有上游
requires关系,因此它的导出包(exports)和开放包(opens)直接面向“外部世界”,比如启动类、反射调用方或服务使用者 - 它的模块描述符一旦解析失败(如缺失依赖、版本不匹配、分裂包冲突),整个应用启动立即终止——这是模块系统强制保障一致性的关键机制
根模块就像一棵树的主干,不靠别的枝干支撑,却决定了整棵树能长多高、往哪伸展、哪些叶子能真正展开。

















