java多模块项目需按依赖顺序逐模块编译,先编译各模块的module-info.java,再编译其余类,并严格使用--module-path指定已编译模块路径。

Java 多模块项目不是靠单条 javac 命令就能“一键编译”的。它需要明确模块边界、依赖顺序和路径组织。手动用 javac 编译,核心是先编译模块声明,再按依赖关系逐个编译,严格使用 --module-path 而非 -cp。
模块化项目必须先编译 module-info.java
每个模块的入口是 module-info.java,它定义了模块名、导出包(exports)、所需依赖(requires)等。这个文件必须最先单独编译,否则其他类会报 module not found 或 package is empty or does not exist。
例如,模块 com.example.util 目录结构为:
mods/util/src/com/example/util/ ├── module-info.java └── StringUtils.java
正确做法:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
# 先编译 module-info.java,输出到 mods/util/classes javac -d mods/util/classes mods/util/src/com/example/util/module-info.java # 再编译其余源文件,把刚生成的 classes 加入 --module-path javac --module-path mods/util/classes -d mods/util/classes mods/util/src/com/example/util/StringUtils.java
依赖模块必须显式提供在 --module-path 中
假设 com.example.app 依赖 com.example.util,且 app 的源码在 mods/app/src/ 下:
- 不能用
-cp mods/util/classes(传统类路径对模块无效); - 必须用
--module-path mods/util/classes,让编译器识别com.example.util是一个已编译模块; -
app自身的module-info.java中需有requires com.example.util;。
编译命令示例:
# 1. 编译 app 的 module-info.java
javac -d mods/app/classes mods/app/src/module-info.java
# 2. 编译 app 其他类,把 util 模块路径传进去
javac --module-path "mods/util/classes:mods/app/classes" \
-d mods/app/classes \
mods/app/src/com/example/app/Main.java
多模块协同编译的关键细节
-
路径分隔符:Linux/macOS 用
:,Windows 用;; -
输出目录要统一:建议每个模块用独立
classes目录,避免 class 文件混杂; -
--add-modules不用于编译:它是运行时参数,编译阶段只靠--module-path+requires; -
跨模块引用必须导出:若
util中的StringUtils要被app使用,module-info.java中必须写exports com.example.util;; - 不能跳过 module-info.java:即使模块只含一个类,也必须有该文件,否则 JVM 不认作模块。
实际编译顺序口诀
先编最底层模块(无 requires 的),再编上层;
每个模块:module-info.java→ 其他.java;
后续模块编译时,前序模块的classes目录必须出现在--module-path中。
不复杂但容易忽略。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










