Maven 新一代构建工具 mvnd
摘要
-
本文介绍 Maven 新一代构建工具 mvnd
-
本文安装的是 mvnd 1.0.3。
mvnd 简介
-
mvnd 是 Maven 新一代构建工具,基于 Netty 构建,使用 Java 语言编写。
-
mvnd 借鉴 Gradle 和 Takari 中的技术从而提供更快的Maven构建速度。
架构概述
-
mvnd内嵌Maven(因此不需要单独安装Maven)。1.x版本内嵌maven3.x版本,2.x版本内嵌maven4.x版本。
-
实际构建发生在一个长驻后台进程中,又名守护程序。
-
一个守护程序实例可以服务来自mvnd客户端的多个连续请求。
-
mvnd客户端是使用GraalVM构建的原生可执行文件。与启动传统的JVM相比,它启动速度更快,占用的内存更少。
-
如果没有闲置守护程序来服务构建请求,则可以并行生成多个守护程序。
-
这种架构带来了以下优点:
- 不需要每次构建重新启动 JVM,大大节省时间。
- 持有Maven插件类的classloaders被缓存在多个构建中。因此,插件jar只被读取和解析一次。Maven插件的SNAPSHOT版本没有缓存。
- JVM内Just-In-Time(JIT)编译器生成的原生代码也被保留。与传统的Maven相比,JIT编译花费的时间更少。在重复构建期间,JIT优化的代码立即可用。这不仅适用于来自Maven插件和Maven Core的代码,也适用于来自JDK本身的所有代码。
-
默认情况下,mvnd 使用多个 CPU 内核并行构建模块,使用的核心数由以下公式给出:
availableProcessors - 1
mvnd 安装
-
mvnd 安装包下载地址:mvnd Github Release
-
本文以 macOS 为例
1 | # 下载 mvnd 对应的安装包 |
-
mvnd 内嵌 maven,其本质上还是依赖于maven,所以需要创建maven的配置文件
~/.m2/settings.xml,由于本机之前安装过 Maven,所以这一步就省略了。 -
[推荐]将 mvnd 的配置文件拷贝到
~/.m2目录下
1 | # 与 maven了类似,`~/.m2/mvnd.properties` 优先级高于 `$MVND_HOME/conf/mvnd.properties` |
-
mvnd 配置项说明,一般不需要修改,可能会修改的我用
[*]做了标注
| 配置项 | 默认值 | 中文解释 |
|---|---|---|
mvnd.noBuffering [*] |
false | 是否禁用输出缓冲,从而像普通 Maven 一样实时显示日志。命令行传递 -B 或 --batch-mode 也会启用此行为 |
| mvnd.rollingWindowSize | 0 | 构建并行模块时,每个模块显示的日志行数 |
| mvnd.logPurgePeriod | 7d | 自动清理日志的周期(如:7天),日志保存路径: $HOME/.m2/mvnd/registry/1.0.3/ |
| mvnd.noDaemon | false | 禁止使用 daemon(守护进程)。一般用于调试,仅在非 native 模式下有效 |
| mvnd.debug | false | 使用调试模式启动 daemon,JVM 参数为:-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8000 |
| mvnd.idleTimeout | 3 hours | 守护进程在空闲多久后自动关闭 |
| mvnd.keepAlive | 100 ms | 如果构建过程没有输出,daemon 向客户端发送保活消息的时间间隔 |
| mvnd.maxLostKeepAlive | 30 | 允许丢失的最大保活消息数量,超过则客户端认为 daemon 已失败 |
| mvnd.minThreads | 1 | 构建时要使用的最少线程数量。如果显式指定了 -T、--threads 或 mvnd.threads,该值将被忽略 |
mvnd.threads [*] |
未设置 | 传递给 daemon 的线程数,与 Maven 的 -T / --threads 语法一致 |
| mvnd.builder | smart | 指定使用的 Maven 构建器名称(等同于 -b 或 --builder) |
| mvnd.minHeapSize | 128M | 守护进程 JVM 的最小堆内存 |
mvnd.maxHeapSize [*] |
2G | 守护进程 JVM 的最大堆内存 |
| mvnd.threadStackSize | 1M | 守护进程线程栈大小 |
| mvnd.jvmArgs | 未设置 | 传递给 daemon 的额外 JVM 参数 |
| mvnd.enableAssertions | false | 是否为 daemon 启用 JVM 断言(-ea) |
| mvnd.expirationCheckDelay | 10 seconds | 守护进程检测自身是否需要过期的时间间隔 |
| mvnd.duplicateDaemonGracePeriod | 10 seconds | 多个 daemon 存在时,多余 daemon 的宽限退出时间 |
| mvnd.home | 自动设置 | mvnd 安装目录,客户端通常会根据 mvnd 可执行文件位置设置 |
| java.home | 使用环境变量 | 启动 daemon 的 Java 目录(等同 JAVA_HOME) |
maven.settings [*] |
~/.m2/settings.xml | maven 的 settings.xml 路径 |
mvnd 使用
-
命令行使用方式与 mvn 一样,比如:
1 | mvnd clean install |
-
mvnd 的 daemon 缓存了一切,所以运行
mvnd clean install后,之后再次运行mvnd clean install时,mvnd 会直接从缓存中读取构建结果,从而节省了构建时间。 -
mvnd 还有些特殊用法,比如:
1 | # 查看当前所有的守护进程列表,守护进程空闲超过 mvnd.idleTimeout=3 hours 会自动关闭 |
-
在IDEA中使用
mvnd,在Maven设置中将mvnd的安装目录添加到Maven Home Path中

mvnd 与 mvnw 的区别
-
我们现在大部分创建的项目都是Springboot项目,通过IDEA创建Springboot项目时会自动创建如下文件
1 | .mvn: 文件夹,其内部存放了 `wrapper/maven-wrapper.properties` 文件,该文件用于声明 mvn 的 url |
-
实际上
mvnw是一个 Maven 启动脚本,用于自动下载指定版本的Maven,并运行 Maven 构建。 -
第一次使用
mvnw时会通过wrapper/maven-wrapper.properties文件中的声明自动下载maven,并保存在~/.m2/wrapper/dists/目录下 -
mvnw使用方式如下:
1 | ./mvnw clean install |
-
运行速度:
mvnd >> mvnw ≈ mvn
| 对比项 | mvnd | mvnw(Maven Wrapper) |
|---|---|---|
| 是什么 | 一个「常驻的 Maven 守护进程」 | 一个「Maven 启动脚本」 |
| 是否常驻 | ✅ 是(daemon) | ❌ 否(一次性) |
| 是否下载 Maven | ❌ 不下载,自己就是程序 | ✅ 会自动下载指定版本 |
| 主要目的 | 加速构建 | 保证版本一致 |
| 是否推荐在 CI | 一般不建议 | ✅ 非常推荐 |
| 使用方式 | mvnd clean install |
./mvnw clean install |
| 是否与项目绑定 | ❌ 全局使用 | ✅ 和项目绑定 |