Maven基础知识(6)- Maven 依赖传递、POM 继承、Maven 聚合
1. Maven 依赖传递
Maven 的依赖传递机制是指:不管 Maven 项目存在多少间接依赖,POM 中都只需要定义其直接依赖,不必定义任何间接依赖。
Maven 会动读取当前项目各个直接依赖的 POM,将那些必要的间接依赖以传递性依赖的形式引入到当前项目中。Maven 的依赖传递机制能够帮助用户一定程度上简化 POM 的配置。
基于 A、B、C 三者的依赖关系,根据 Maven 的依赖传递机制,我们只需要在项目 A 的 POM 中定义其直接依赖 B,在项目 B 的 POM 中定义其直接依赖 C,Maven 会解析 A 的直接依赖 B 的 POM ,将间接依赖 C 以传递性依赖的形式引入到项目 A 中。
通过这种依赖传递关系,可以使依赖关系树迅速增长到一个很大的量级,很有可能会出现依赖重复,依赖冲突等情况,Maven 针对这些情况提供了如下功能进行处理:
(1) 依赖范围(Dependency scope)
(2) 依赖调解(Dependency mediation)
(3) 可选依赖(Optional dependencies)
(4) 排除依赖(Excluded dependencies)
(5) 依赖管理(Dependency management)
1) 依赖范围(Dependency scope)
Maven 在对项目进行编译、测试和运行时,会分别使用三套不同的 classpath:
(1) 编译时: Maven 会将与编译相关的依赖引入到编译 classpath 中;
(2) 测试时: Maven 会将与测试相关的的依赖引入到测试 classpath 中;
(3) 运行时,Maven 会将与运行相关的依赖引入到运行 classpath 中。
我们可以在 POM 的依赖声明使用 scope 元素来控制依赖与三种 classpath(编译 classpath、测试 classpath、运行 classpath )之间的关系,这就是依赖范围。
Maven 具有以下 6 中常见的依赖范围,如下表所示。
依赖范围 | 描述 |
compile | 编译依赖范围,scope 元素的缺省值。使用此依赖范围的 Maven 依赖,对于三种 classpath 均有效,即该 Maven 依赖在上述三种 classpath 均会被引入。例如,log4j 在编译、测试、运行过程都是必须的。 |
test | 测试依赖范围。使用此依赖范围的 Maven 依赖,只对测试 classpath 有效。例如,Junit 依赖只有在测试阶段才需要。 |
provided | 已提供依赖范围。使用此依赖范围的 Maven 依赖,只对编译 classpath 和测试 classpath 有效。例如,servlet-api 依赖对于编译、测试阶段而言是需要的,但是运行阶段,由于外部容器已经提供,故不需要 Maven 重复引入该依赖。 |
runtime | 运行时依赖范围。使用此依赖范围的 Maven 依赖,只对测试 classpath、运行 classpath 有效。例如,JDBC 驱动实现依赖,其在编译时只需 JDK 提供的 JDBC 接口即可,只有测试、运行阶段才需要实现了 JDBC 接口的驱动。 |
system | 系统依赖范围,其效果与 provided 的依赖范围一致。其用于添加非 Maven 仓库的本地依赖,通过依赖元素 dependency 中的 systemPath 元素指定本地依赖的路径。鉴于使用其会导致项目的可移植性降低,一般不推荐使用。 |
import | 导入依赖范围,该依赖范围只能与 dependencyManagement 元素配合使用,其功能是将目标 pom.xml 文件中 dependencyManagement 的配置导入合并到当前 pom.xml 的 dependencyManagement 中。 |
依赖范围与三种 classpath 的关系一览表,如下所示。
依赖范围 | 编译 classpath | 测试 classpath | 运行 classpath | 实例 |
compile | √ | √ | √ | log4j |
test | - | √ | - | junit |
provided | √ | √ | - | servlet-api |
runtime | - | √ | √ | JDBC-driver |
system | √ | √ | - | 非 Maven 仓库的本地依赖 |
依赖范围对传递依赖的影响:
项目 A 依赖于项目 B,B 又依赖于项目 C,此时我们可以将 A 对于 B 的依赖称之为第一直接依赖,B 对于 C 的依赖称之为第二直接依赖。
B 是 A 的直接依赖,C 是 A 的间接依赖,根据 Maven 的依赖传递机制,间接依赖 C 会以传递性依赖的形式引入到 A 中,但这种引入并不是无条件的,它会受到依赖范围的影响。
传递性依赖的依赖范围受第一直接依赖和第二直接依赖的范围影响,如下表所示。
compile | test | provided | runtime | |
compile | compile | - | - | runtime |
test | test | - | - | test |
provided | provided | - | provided | provided |
runtime | runtime | - | - | runtime |
注:上表中,左边第一列表示第一直接依赖的依赖范围,上边第一行表示第二直接依赖的依赖范围。交叉部分的单元格的取值为传递性依赖的依赖范围,若交叉单元格取值为 “-”,则表示该传递性依赖不能被传递。
通过上表,可以总结出以下规律:
(1) 当第二直接依赖的范围是 compile 时,传递性依赖的范围与第一直接依赖的范围一致;
(2) 当第二直接依赖的范围是 test 时,传递性依赖不会被传递;
(3) 当第二直接依赖的范围是 provided 时,只传递第一直接依赖的范围也为 provided 的依赖,且传递性依赖的范围也为 provided;
(4) 当第二直接依赖的范围是 runtime 时,传递性依赖的范围与第一直接依赖的范围一致,但 compile 例外,此时传递性依赖的范围为 runtime。
2) 依赖调解(Dependency mediation)
Maven 的依赖传递机制可以简化依赖的声明,用户只需要关心项目的直接依赖,而不必关心这些直接依赖会引入哪些间接依赖。但当一个间接依赖存在多条引入路径时,为了避免出现依赖重复的问题,Maven 通过依赖调节来确定间接依赖的引入路径。
依赖调节遵循以下两条原则:
a) 引入路径短者优先
b) 先声明者优先
以上两条原则,优先使用第一条原则解决,第一条原则无法解决,再使用第二条原则解决。
(1) 引入路径短者优先
引入路径短者优先,顾名思义,当一个间接依赖存在多条引入路径时,引入路径短的会被解析使用。
例如,A 存在这样的依赖关系:
A->B->C->D(1.0)
A->X->D(2.0)
D 是 A 的间接依赖,但两条引入路径上有两个不同的版本,很显然不能同时引入,否则造成重复依赖的问题。
根据 Maven 依赖调节的第一个原则:引入路径短者优先,D(1.0)的路径长度为 3,D(2.0)的路径长度为 2,因此间接依赖 D(2.0)将从 A->X->D(2.0) 路径引入到 A 中。
(2) 先声明者优先
先声明者优先,顾名思义,在引入路径长度相同的前提下,POM 文件中依赖声明的顺序决定了间接依赖会不会被解析使用,顺序靠前的优先使用。
例如,A 存在以下依赖关系:
A->B->D(1.0)
A->X->D(2.0)
D 是 A 的间接依赖,其两条引入路径的长度都是 2,此时 Maven 依赖调节的第一原则已经无法解决,需要使用第二原则:先声明者优先。
A 的 POM 文件中配置如下。
1 <dependencies> 2 ... 3 <dependency> 4 ... 5 <artifactId>B</artifactId> 6 ... 7 </dependency> 8 ... 9 <dependency> 10 ... 11 <artifactId>X</artifactId> 12 ... 13 </dependency> 14 ... 15 </dependencies>
以上配置可以看出,由于 B 的依赖声明比 X 靠前,所以间接依赖 D(1.0)将从 A->B->D(1.0) 路径引入到 A 中。
3) 排除依赖(Excluded dependencies)
假设存在这样的依赖关系,A 依赖于 B,B 依赖于 X,B 又依赖于 Y。B 实现了两个特性,其中一个特性依赖于 X,另一个特性依赖于 Y,且两个特性是互斥的关系,用户无法同时使用两个特性,所以 A 需要排除 X,此时就可以在 A 中将间接依赖 X 排除。
X Y
\ /
B
|
A
排除依赖是通过在 A 中使用 exclusions 元素实现的,该元素下可以包含若干个 exclusion 子元素,用于排除若干个间接依赖,示例代码如下。
1 <project xmlns="http://maven.apache.org/POM/4.0.0" 2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 4 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 5 6 <modelVersion>4.0.0</modelVersion> 7 <groupId>com.example</groupId> 8 <artifactId>A</artifactId> 9 <version>1.0-SNAPSHOT</version> 10 <dependencies> 11 <dependency> 12 <groupId>com.example</groupId> 13 <artifactId>B</artifactId> 14 <version>1.0-SNAPSHOT</version> 15 <exclusions> 16 <!-- 设置排除 --> 17 <!-- 排除依赖必须基于直接依赖中的间接依赖设置为可以依赖为 false --> 18 <!-- 设置当前依赖中是否使用间接依赖 --> 19 <exclusion> 20 <!--设置具体排除--> 21 <groupId>com.example</groupId> 22 <artifactId>X</artifactId> 23 </exclusion> 24 </exclusions> 25 </dependency> 26 </dependencies> 27 </project>
关于 exclusions 元素及排除依赖说明如下:
(1) 排除依赖是控制当前项目是否使用其直接依赖传递下来的接间依赖;
(2) exclusions 元素下可以包含若干个 exclusion 子元素,用于排除若干个间接依赖;
(3) exclusion 元素用来设置具体排除的间接依赖,该元素包含两个子元素:groupId 和 artifactId,用来确定需要排除的间接依赖的坐标信息;
(4) exclusion 元素中只需要设置 groupId 和 artifactId 就可以确定需要排除的依赖,无需指定版本 version。
4) 可选依赖(Optional Dependencies)
与上文的应用场景相同,也是 A 希望排除间接依赖 X,除了在 B 中设置可选依赖外,我们还可以在 B 中将 X 设置为可选依赖。
在 B 的 POM 关于 X 的依赖声明中使用 optional 元素,将其设置成可选依赖,示例配置如下。
1 <project xmlns="http://maven.apache.org/POM/4.0.0" 2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 4 http://maven.apache.org/maven-v4_0_0.xsd"> 5 6 <modelVersion>4.0.0</modelVersion> 7 <groupId>com.example</groupId> 8 <artifactId>B</artifactId> 9 <packaging>jar</packaging> 10 <version>1.0-SNAPSHOT</version> 11 <dependencies> 12 <dependency> 13 <groupId>com.example</groupId> 14 <artifactId>X</artifactId> 15 <version>1.0-SNAPSHOT</version> 16 <!--设置可选依赖 --> 17 <optional>true</optional> 18 </dependency> 19 </dependencies> 20 </project>
关于 optional 元素及可选依赖说明如下:
(1) 可选依赖用来控制当前依赖是否向下传递成为间接依赖;
(2) optional 默认值为 false,表示可以向下传递称为间接依赖;
(3) 若 optional 元素取值为 true,则表示当前依赖不能向下传递成为间接依赖。
排除依赖和可选依赖都能在项目中将间接依赖排除在外,但两者实现机制却完全不一样。
(1) 排除依赖是控制当前项目是否使用其直接依赖传递下来的接间依赖;
(2) 可选依赖是控制当前项目的依赖是否向下传递;
(3) 可选依赖的优先级高于排除依赖;
(4) 若对于同一个间接依赖同时使用排除依赖和可选依赖进行设置,那么可选依赖的取值必须为 false,否则排除依赖无法生效。
2. POM 继承
Maven 的依赖传递机制可以一定程度上简化 POM 的配置,但这仅限于存在依赖关系的项目或模块中。当一个项目的多个模块都依赖于相同 jar 包的相同版本,且这些模块之间不存在依赖关系,这就导致同一个依赖需要在多个模块中重复声明,这显然是不可取的,大量的前人经验告诉我们,重复往往意味着更多的劳动和更高的潜在风险。
在 Java 面向对象中,我们可以建立一种类的父子结构,然后在父类中声明一些字段和方法供子类继承,这样就可以一定程度上消除重复,做到 “一处声明,多处使用”。在 Maven 的世界中,也有类似的机制,它就是 POM 继承。
Maven 在设计时,借鉴了 Java 面向对象中的继承思想,提出了 POM 继承思想。当一个项目包含多个模块时,可以在该项目中再创建一个父模块,并在其 POM 中声明依赖,其他模块的 POM 可通过继承父模块的 POM 来获得对相关依赖的声明。
对于父模块而言,其目的是为了消除子模块 POM 中的重复配置,其中不包含有任何实际代码,因此父模块 POM 的打包类型(packaging)必须是 pom。
Maven 可通过继承获得 POM 元素,如下表。
元素 | 描述 |
groupId | 项目组 ID,项目坐标的核心元素 |
version | 项目版本,项目坐标的核心元素 |
description | 项目的描述信息 |
organization | 项目的组织信息 |
inceptionYear | 项目的创始年份 |
url | 项目的 URL 地址 |
developers | 项目的开发者信息 |
contributors | 项目的贡献者信息 |
distributionManagement | 项目的部署配置 |
issueManagement | 项目的缺陷跟踪系统信息 |
ciManagement | 项目的持续集成系统信息 |
scm | 项目的版本控制系统信息 |
mailingLists | 项目的邮件列表信息 |
properties | 自定义的 Maven 属性 |
dependencies | 项目的依赖配置 |
dependencyManagement | 项目的依赖管理配置 |
repositories | 项目的仓库配置 |
build | 包括项目的源码目录配置、输出目录配置、插件配置、插件管理配置等 |
reporting | 包括项目的报告输出目录配置、报告插件配置等 |
示例,一个项目中存在如下多个模块。
junit_3.8.1 mariadb-java-client_2.7.4
\ /
MavenDemo04_1.0
/ \
CoreLib_1.0 DataLib_1.0
\ /
UIDemo_1.0
如上图所示:
(1) UIDemo_1.0 依赖于 CoreLib_1.0 和 DataLib_1.0;
(2) MavenDemo04_1.0 是 CoreLib_1.0 和 DataLib_1.0 的父模块;
(3) MavenDemo04_1.0 依赖于 junit_3.8.1、mariadb-java-client_2.7.4;
1) 创建 MavenDemo04 项目
打开 cmd 命令行窗口,进入 D:\Workshop\maven 目录,运行以下命令:
D:\Workshop\maven>mvn archetype:generate -DgroupId=com.example -DartifactId=MavenDemo04 -DinteractiveMode=false
项目 MavenDemo04 创建成功,手动删除 src 目录,并修改 pom.xml 配置:
1 <project xmlns="http://maven.apache.org/POM/4.0.0" 2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 4 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 5 6 <modelVersion>4.0.0</modelVersion> 7 <groupId>com.example</groupId> 8 <artifactId>MavenDemo04</artifactId> 9 <version>1.0</version> 10 <packaging>pom</packaging> 11 12 <dependencies> 13 <dependency> 14 <groupId>junit</groupId> 15 <artifactId>junit</artifactId> 16 <version>3.8.1</version> 17 <scope>test</scope> 18 </dependency> 19 <dependency> 20 <groupId>org.mariadb.jdbc</groupId> 21 <artifactId>mariadb-java-client</artifactId> 22 <version>2.7.4</version> 23 <scope>runtime</scope> 24 </dependency> 25 </dependencies> 26 </project>
修改打包类型(packaging)为 pom,并声明了 2 个依赖:junit 3.8.1、mariadb-java-client 2.7.4,把 Version 从 1.0-SNAPSHOT 改成 1.0。
2) 创建 CoreLib 模块
进入 D:\Workshop\maven\MavenDemo04 目录,运行以下命令:
D:\Workshop\maven\MavenDemo04>mvn archetype:generate -DgroupId=com.example -DartifactId=CoreLib -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
模块 CoreLib 创建成功,程序会自动在 MavenDemo04 的 pom.xml 里添加如下代码:
1 <project>
2 ...
3 <modules>
4 <module>CoreLib</module>
5 </modules>
6 </project>
修改 CoreLib 的pom.xml 配置
1 <?xml version="1.0"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 5 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 6 7 <parent> 8 <groupId>com.example</groupId> 9 <artifactId>MavenDemo04</artifactId> 10 <version>1.0</version> 11 </parent> 12 13 <modelVersion>4.0.0</modelVersion> 14 <artifactId>CoreLib</artifactId> 15 16 <name>CoreLib</name> 17 <url>http://maven.apache.org</url> 18 19 <dependencies> 20 <dependency> 21 <groupId>log4j</groupId> 22 <artifactId>log4j</artifactId> 23 <version>1.2.17</version> 24 </dependency> 25 </dependencies> 26 </project>
子模块 CoreLib 的 pom.xml 中使用 parent 元素声明父模块,其子元素如下表:
元素 | 描述 |
groupId | 父模块的项目组 id,必选项。 |
artifactId | 父模块 id,必选项。 |
version | 父模块版本,必选项。 |
relativePath | 父模块 POM 的相对路径,默认值为 ../pom.xml。项目构建时,Maven 会先根据 relativePath 查找父模块 POM,如果找不到,再从本地仓库或远程仓库中查找。可选项 |
子模块的 POM 中,当前模块的 groupId 和 version 元素可以省略,但这并不意味着当前模块没有 groupId 和 version,子模块会隐式的从父模块中继承这两个元素,即由父模块控制子模块的公司组织 id 以及版本,这样可以简化 POM 的配置。
3) 创建 DataLib 模块
进入 D:\Workshop\maven\MavenDemo04 目录,运行以下命令:
D:\Workshop\maven\MavenDemo04>mvn archetype:generate -DgroupId=com.example -DartifactId=DataLib -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
模块 DataLib 创建成功,程序会自动在 MavenDemo04 的 pom.xml 里添加如下代码:
1 <project>
2
3 ...
4
5 <modules>
6 ...
7 <module>DataLib</module>
8 </modules>
9 </project>
修改 DataLib 的 pom.xml 配置
1 <?xml version="1.0"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 5 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 6 7 <parent> 8 <groupId>com.example</groupId> 9 <artifactId>MavenDemo04</artifactId> 10 <version>1.0</version> 11 </parent> 12 13 <modelVersion>4.0.0</modelVersion> 14 <artifactId>DataLib</artifactId> 15 16 <name>DataLib</name> 17 <url>http://maven.apache.org</url> 18 19 </project>
4) 创建 UIDemo 模块
进入 D:\Workshop\maven\MavenDemo04 目录,运行以下命令:
D:\Workshop\maven\MavenDemo04>mvn archetype:generate -DgroupId=com.example -DartifactId=UIDemo -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
模块 UIDemo 创建成功,程序会自动在 MavenDemo04 的 pom.xml 里添加如下代码:
1 <project>
2
3 ...
4
5 <modules>
6 ...
7 <module>UIDemo</module>
8 </modules>
9 </project>
修改 UIDemo 的 pom.xml 配置
1 <?xml version="1.0"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 5 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 6 7 <parent> 8 <groupId>com.example</groupId> 9 <artifactId>MavenDemo04</artifactId> 10 <version>1.0</version> 11 </parent> 12 13 <modelVersion>4.0.0</modelVersion> 14 <artifactId>UIDemo</artifactId> 15 16 <name>UIDemo</name> 17 <url>http://maven.apache.org</url> 18 19 <properties> 20 <!-- 主项目运行 mvn install 时不执行本模块 --> 21 <maven.install.skip>true</maven.install.skip> 22 </properties> 23 24 <dependencies> 25 <dependency> 26 <groupId>com.example</groupId> 27 <artifactId>CoreLib</artifactId> 28 <version>1.0</version> 29 </dependency> 30 <dependency> 31 <groupId>com.example</groupId> 32 <artifactId>DataLib</artifactId> 33 <version>1.0</version> 34 </dependency> 35 </dependencies> 36 </project>
安装 CoreLib、DataLib 包到本地 Maven 仓库,运行以下命令:
D:\Workshop\maven\MavenDemo04>mvn install
编译 UIDemo 模块,运行以下命令:
D:\Workshop\maven\MavenDemo04\UIDemo>mvn compile
编译结果如下:
[INFO] Scanning for projects... [INFO] [INFO] -------------------------< com.example:UIDemo >------------------------- [INFO] Building UIDemo 1.0 [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ UIDemo --- [WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent! [INFO] skip non existing resourceDirectory D:\Workshop\maven\MavenDemo04\UIDemo\src\main\resources [INFO] [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ UIDemo --- [INFO] Nothing to compile - all classes are up to date [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 0.590 s [INFO] Finished at: 2022-06-19T13:02:24+08:00 [INFO] ------------------------------------------------------------------------
注:因为子模块的 pom 继承了主项目的 pom,主项目 MavenDemo04 也需要作为 pom 包被安装。主项目下不需要安装的子模块,在该子模块的 pom 里添加 <maven.install.skip>true</maven.install.skip>。
5) 查看继承依赖项
在 CoreLib 和 DataLib 两个子模块的 pom.xml 中,只有 CoreLib 声明了一个依赖:log4j 1.2.17。那么如何验证子模块是否继承了父模块 POM 中声明的依赖项呢?
使用 mvn dependency:list 能够列出项目最终解析到的依赖列表,mvn dependency:tree 能够进一步的描绘项目依赖树。
进入 D:\Workshop\maven\MavenDemo04\CoreLib 目录,运行以下命令:
D:\Workshop\maven\MavenDemo04\CoreLib>mvn dependency:list
显示结果如下:
[INFO] Scanning for projects... [INFO] [INFO] ------------------------< com.example:CoreLib >------------------------- [INFO] Building CoreLib 1.0 [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- maven-dependency-plugin:2.8:list (default-cli) @ CoreLib --- [INFO] [INFO] The following files have been resolved: [INFO] org.mariadb.jdbc:mariadb-java-client:jar:2.7.4:runtime [INFO] junit:junit:jar:3.8.1:test [INFO] log4j:log4j:jar:1.2.17:compile [INFO] [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 0.862 s [INFO] Finished at: 2022-06-06T19:40:23+08:00 [INFO] ------------------------------------------------------------------------
3. Maven 聚合
使用 Maven 聚合功能对项目进行构建时,需要在该项目中额外创建一个的聚合模块,然后通过这个模块构建整个项目的所有模块。聚合模块仅仅是帮助聚合其他模块的工具,其本身并无任何实质内容,因此聚合模块中只有一个 POM 文件,不包含 src 等目录。
与父模块相似,聚合模块的打包方式(packaging)也是 pom,用户可以在其 POM 中通过 modules 下的 module 子元素来添加需要聚合的模块的目录路径。
很显然,上文创建的 MavenDemo04 项目就是一个 Maven 聚合项目,MavenDemo04 的 pom.xml 文件的 <modules> 把子模块聚会起来。
1 <modules> 2 <module>CoreLib</module> 3 <module>DataLib</module> 4 <module>UIDemo</module> 5 </modules>
打开 cmd 命令行窗口,进入 D:\Workshop\maven\MavenDemo04 目录,运行以下命令:
D:\Workshop\maven\MavenDemo04>mvn clean install
显示结果如下:
[INFO] Scanning for projects... [INFO] ------------------------------------------------------------------------ [INFO] Reactor Build Order: [INFO] [INFO] MavenDemo04 [pom] [INFO] CoreLib [jar] [INFO] DataLib [jar] [INFO] UIDemo [jar] [INFO] [INFO] ----------------------< com.example:MavenDemo04 >----------------------- [INFO] Building MavenDemo04 1.0 [1/4] [INFO] --------------------------------[ pom ]--------------------------------- ... [INFO] [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ UIDemo --- [INFO] Building jar: D:\Workshop\maven\MavenDemo04\UIDemo\target\UIDemo-1.0.jar [INFO] [INFO] --- maven-install-plugin:2.4:install (default-install) @ UIDemo --- [INFO] Skipping artifact installation [INFO] ------------------------------------------------------------------------ [INFO] Reactor Summary for MavenDemo04 1.0: [INFO] [INFO] MavenDemo04 ........................................ SUCCESS [ 0.563 s] [INFO] CoreLib ............................................ SUCCESS [ 2.999 s] [INFO] DataLib ............................................ SUCCESS [ 0.578 s] [INFO] UIDemo ............................................. SUCCESS [ 0.468 s] [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 4.771 s [INFO] Finished at: 2022-06-19T13:48:46+08:00 [INFO] ------------------------------------------------------------------------