mvnd:让 Maven 构建速度提升 2-10 倍的神器
Maven Daemon (mvnd) - 更快的 Maven 构建工具
性能提升:比传统 Maven 快 2-10 倍
适用场景:Java 项目构建、CI/CD 流水线、本地开发
官方地址:https://github.com/apache/maven-mvnd
mvnd 是什么?
Maven Daemon (mvnd) 简介
mvnd = Maven Daemon,即 Maven 守护进程。
┌────────────────────────────────────────────────────────────┐
│ 什么是 mvnd? │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ mvnd = Maven + Daemon + GraalVM + Smart Builder │ │
│ │ │ │
│ │ ✓ 内嵌 Maven(无需单独安装) │ │
│ │ ✓ 守护进程常驻后台 │ │
│ │ ✓ GraalVM 原生编译 │ │
│ │ ✓ 智能构建策略 │ │
│ │ ✓ 类加载器缓存 │ │
│ │ ✓ JIT 编译优化 │ │
│ │ │ │
│ └──────────────────────────────────────────────────────┘ │
└────────────────────────────────────────────────────────────┘
项目信息:
官方地址:https://github.com/apache/maven-mvnd
项目归属:Apache Maven 官方子项目
开发团队:Red Hat + Apache Maven 团队
当前版本:
1.x 稳定版(嵌入 Maven 3.9.x)
2.x 预览版(嵌入 Maven 4.0.x)
Star 数量:3.3k+
开源协议:Apache License 2.0
诞生背景: Maven 构建速度慢一直被诟病,尤其是与 Gradle 对比时。mvnd 的诞生就是为了解决这个问题,它借鉴了:
Gradle Daemon:守护进程技术
Takari Smart Builder:智能并行构建
GraalVM:原生编译技术
mvnd vs Maven:核心区别 {#核心区别}
架构对比
┌─────────────────────────────────────────────────────────────┐
│ 传统 Maven 架构 │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ 每次构建 │ │
│ │ ↓ │ │
│ │ 启动新的 JVM → 加载 Maven → 加载插件 → 执行构建 │ │
│ │ ↓ │ │
│ │ JVM 退出 │ │
│ │ │ │
│ │ ⏱️ 启动时间:每次 2-5 秒 │ │
│ │ 💾 内存占用:每次重新分配 │ │
│ │ 🔄 类加载:每次重新加载 │ │
│ │ 🚀 JIT 优化:从零开始 │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ mvnd 架构 │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ 首次构建 │ │
│ │ ↓ │ │
│ │ 启动 Daemon → 加载 Maven → 加载插件 → 执行构建 │ │
│ │ ↓ │ │
│ │ Daemon 保持运行(后台守护进程) │ │
│ │ │ │
│ │ 后续构建 │ │
│ │ ↓ │ │
│ │ GraalVM Client 连接 Daemon → 立即执行构建 │ │
│ │ │ │
│ │ ⏱️ 启动时间:<100ms │ │
│ │ 💾 内存占用:Daemon 复用 │ │
│ │ 🔄 类加载:缓存复用 │ │
│ │ 🚀 JIT 优化:热点代码立即可用 │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
核心区别表
关键技术差异
1. 守护进程 (Daemon)
# Maven:每次构建都是全新进程
$ mvn clean install
[INFO] Scanning for projects...
[启动 JVM 2-5秒]
[加载 Maven]
[加载插件]
[执行构建]
[JVM 退出]
# mvnd:首次启动 Daemon,后续复用
$ mvnd clean install
[首次] 启动 Daemon (5秒) → 执行构建
[后续] 连接 Daemon (<100ms) → 立即构建
2. GraalVM 客户端
传统 Maven 客户端:
- 基于 Java
- 启动需要 JVM
- 内存占用:~100MB
mvnd 客户端:
- GraalVM 原生编译
- 启动 <100ms
- 内存占用:~10MB
3. 智能并行构建
Maven 并行构建(-T 参数):
- 简单的线程池
- 模块间依赖关系处理简单
- 可能存在等待
mvnd Smart Builder:
- 借鉴 Takari Smart Builder
- 更智能的调度策略
- 最大化并行度
mvnd 工作原理 {#工作原理}
架构图
┌─────────────────────────────────────────────────────────────┐
│ mvnd 架构详解 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ │
│ │ mvnd Client │ (GraalVM 原生编译) │
│ │ (快速启动) │ │
│ └──────┬───────┘ │
│ │ │
│ │ Socket 连接 │
│ ↓ │
│ ┌──────────────────────────────────────────────┐ │
│ │ mvnd Daemon (守护进程) │ │
│ │ ┌────────────────────────────────────────┐ │ │
│ │ │ JVM (常驻) │ │ │
│ │ │ ┌──────────────────────────────────┐ │ │ │
│ │ │ │ Maven Core │ │ │ │
│ │ │ ├──────────────────────────────────┤ │ │ │
│ │ │ │ 插件类加载器缓存 │ │ │ │
│ │ │ │ • maven-compiler-plugin │ │ │ │
│ │ │ │ • maven-surefire-plugin │ │ │ │
│ │ │ │ • spring-boot-maven-plugin │ │ │ │
│ │ │ ├──────────────────────────────────┤ │ │ │
│ │ │ │ JIT 编译缓存 │ │ │ │
│ │ │ │ • 热点代码优化 │ │ │ │
│ │ │ │ • 方法内联 │ │ │ │
│ │ │ └──────────────────────────────────┘ │ │ │
│ │ └──────────────────────────────────────────┘ │ │
│ └──────────────────────────────────────────────┘ │
│ │
│ 特性: │
│ ✓ 多个 Daemon 可并行运行 │
│ ✓ Daemon 空闲超时自动退出 │
│ ✓ 自动重启崩溃的 Daemon │
└─────────────────────────────────────────────────────────────┘
执行流程
用户执行命令:mvnd clean install
↓
┌────────────────────────────────────────────────┐
│ 1. mvnd Client 启动 (<100ms) │
│ - GraalVM 原生编译,启动极快 │
└────────────────────────────────────────────────┘
↓
┌────────────────────────────────────────────────┐
│ 2. 查找可用的 Daemon │
│ - 检查已运行的 Daemon │
│ - 如果没有 → 启动新 Daemon (首次5秒) │
│ - 如果有空闲 → 直接使用 │
└────────────────────────────────────────────────┘
↓
┌────────────────────────────────────────────────┐
│ 3. Client 连接 Daemon │
│ - 通过 Socket 通信 │
│ - 传递构建参数 │
└────────────────────────────────────────────────┘
↓
┌────────────────────────────────────────────────┐
│ 4. Daemon 执行构建 │
│ - 从缓存加载插件类(无需重新加载) │
│ - JIT 优化代码立即可用 │
│ - Smart Builder 智能并行 │
└────────────────────────────────────────────────┘
↓
┌────────────────────────────────────────────────┐
│ 5. 构建完成 │
│ - Daemon 保持运行(等待下次请求) │
│ - Client 退出 │
└────────────────────────────────────────────────┘
核心优化技术
1. 类加载器缓存
// Maven:每次构建重新加载插件
mvn clean install // 加载 maven-compiler-plugin
mvn clean install // 再次加载 maven-compiler-plugin(浪费)
// mvnd:插件类缓存在 Daemon 中
mvnd clean install // 加载 maven-compiler-plugin
mvnd clean install // 复用已加载的类(快!)
注意:SNAPSHOT 版本的插件不会被缓存,确保开发时的灵活性。
2. JIT 编译优化
首次构建(Cold Start):
- JIT 编译器识别热点代码
- 将字节码编译为本机代码
- 进行方法内联、循环优化等
后续构建(Hot Start):
- JIT 优化的代码立即可用
- 无需重新编译
- 性能提升 20-50%
3. Smart Builder 并行策略
Maven 并行构建:
module-a ─┐
module-b ─┼─ 并行执行(简单)
module-c ─┘
mvnd Smart Builder:
module-a ───────┐
module-b ──┐ │
module-c ──┼────┼─ 智能调度(考虑依赖关系)
module-d ──┘ │
module-e ───────┘
性能对比测试 {#性能对比}
测试环境
硬件配置:
CPU: Intel Core i7-9750H @ 2.6GHz (6核12线程)
内存: 16GB DDR4
硬盘: NVMe SSD
软件版本:
JDK: OpenJDK 17
Maven: 3.9.6
mvnd: 1.0-m8
Gradle: 8.5
测试项目:
类型: Spring Boot 多模块项目
模块数: 5个
代码行数: ~10,000行
测试结果
场景一:单模块项目(小型)
性能提升:
mvnd 首次:135% (相比 Maven)
mvnd 热启动:283% (相比 Maven)
场景二:多模块项目(中型,5个模块)
性能提升:
mvnd 首次 vs Maven (-T4):123%
mvnd 热启动 vs Maven (-T4):210%
mvnd 热启动 vs Maven (-T1):284%
场景三:大型项目(20+模块)
性能提升分析
┌────────────────────────────────────────────────────────────┐
│ mvnd 性能提升来源分析 │
├────────────────────────────────────────────────────────────┤
│ │
│ 📊 性能提升构成: │
│ │
│ ┌──────────────────────────────────────────┐ │
│ │ JVM 启动时间节省 : 30-40% │ │
│ │ 类加载缓存 : 20-30% │ │
│ │ JIT 编译优化 : 15-25% │ │
│ │ Smart Builder 并行优化 : 10-20% │ │
│ │ 其他优化 : 5-10% │ │
│ └──────────────────────────────────────────┘ │
│ │
│ 💡 最佳场景: │
│ • 频繁构建(本地开发) → 热启动优势明显 │
│ • 多模块项目 → 并行构建优势明显 │
│ • 中小型项目 → 综合性能最优 │
│ │
│ ⚠️ 提升有限的场景: │
│ • CI/CD(单次构建) → 只有首次构建,优势不明显 │
│ • 超大型项目(100+模块) → 内存压力增大 │
└────────────────────────────────────────────────────────────┘
安装 mvnd {#安装-mvnd}
前置要求
必需:
- JDK: 11+ (推荐 JDK 17 或 21)
可选:
- Maven: 不需要!mvnd 内嵌了 Maven
重要:mvnd 版本与 JDK 的对应关系
Windows 安装 {#windows-安装}
方法一:手动安装(推荐)
步骤 1:下载 mvnd
访问官方下载页面:https://downloads.apache.org/maven/mvnd/
# 下载最新版本(示例:1.0-m8)
# 选择 windows-amd64 版本
# 例如:mvnd-1.0-m8-windows-amd64.zip
步骤 2:解压到指定目录
# 解压到无空格的路径(推荐)
# 例如:D:\tools\mvnd-1.0-m8-windows-amd64\
步骤 3:配置环境变量
# 方式一:通过图形界面
# 1. 右键"此电脑" → 属性 → 高级系统设置 → 环境变量
# 2. 在"系统变量"中新建:
# 变量名:MVND_HOME
# 变量值:D:\tools\mvnd-1.0-m8-windows-amd64
# 3. 编辑 Path 变量,添加:
# %MVND_HOME%\bin
# 方式二:通过 PowerShell(需要管理员权限)
[System.Environment]::SetEnvironmentVariable('MVND_HOME', 'D:\tools\mvnd-1.0-m8-windows-amd64', 'Machine')
$path = [System.Environment]::GetEnvironmentVariable('Path', 'Machine')
$newPath = $path + ';%MVND_HOME%\bin'
[System.Environment]::SetEnvironmentVariable('Path', $newPath, 'Machine')
步骤 4:验证安装
# 重新打开 PowerShell 或 CMD
mvnd --version
# 输出示例:
# mvnd native client 1.0-m8-windows-amd64
# Terminal: org.jline.terminal.impl.jansi.win.JansiWinSysTerminal
# Apache Maven 3.9.6 (...)
# Maven home: D:\tools\mvnd-1.0-m8-windows-amd64\mvn
# Java version: 17.0.9, vendor: Oracle Corporation
步骤 5:配置 mvnd(可选)
# 复用 Maven 配置
# 编辑 D:\tools\mvnd-1.0-m8-windows-amd64\conf\mvnd.properties
# 添加以下内容:
# 指定 Maven settings.xml 路径(注意:使用 / 而不是 \)
maven.settings=D:/apache-maven-3.9.6/conf/settings.xml
# 指定 JDK 路径(可选)
java.home=D:/Java/jdk-17
# 配置 Daemon 数量(默认是 CPU 核心数-1)
mvnd.maxDaemons=4
# 配置 Daemon 空闲超时(默认 3 小时)
mvnd.idleTimeout=3h
方法二:使用 Chocolatey
# 安装 Chocolatey(如果还没安装)
Set-ExecutionPolicy Bypass -Scope Process -Force
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072
iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
# 使用 Chocolatey 安装 mvnd
choco install mvnd
# 验证
mvnd --version
macOS 安装 {#macos-安装}
方法一:使用 Homebrew(推荐)
# 安装 mvnd 1.x 版本(稳定版,嵌入 Maven 3.9.x)
brew install mvnd@1
# 或安装 mvnd 2.x 预览版(嵌入 Maven 4.0.x)
brew install mvnd
# 验证安装
mvnd --version
方法二:使用 SDKMAN!(推荐)
# 安装 SDKMAN!
curl -s "https://get.sdkman.io" | bash
source "$HOME/.sdkman/bin/sdkman-init.sh"
# 安装 mvnd
sdk install mvnd
# 查看可用版本
sdk list mvnd
# 安装特定版本
sdk install mvnd 1.0-m8
# 切换版本
sdk use mvnd 1.0-m8
# 验证
mvnd --version
方法三:手动安装
# 下载 mvnd
cd ~/Downloads
curl -LO https://downloads.apache.org/maven/mvnd/1.0-m8/mvnd-1.0-m8-darwin-amd64.tar.gz
# 解压到指定目录
sudo tar -xzf mvnd-1.0-m8-darwin-amd64.tar.gz -C /usr/local/
sudo mv /usr/local/mvnd-1.0-m8-darwin-amd64 /usr/local/mvnd
# 配置环境变量
echo 'export MVND_HOME=/usr/local/mvnd' >> ~/.zshrc
echo 'export PATH=$MVND_HOME/bin:$PATH' >> ~/.zshrc
# 重新加载配置
source ~/.zshrc
# 验证
mvnd --version
配置 Bash/Zsh 自动补全
# 对于 Bash 用户
echo 'source $MVND_HOME/bin/mvnd-bash-completion.bash' >> ~/.bashrc
source ~/.bashrc
# 对于 Zsh 用户(oh-my-zsh)
echo 'source $MVND_HOME/bin/mvnd-bash-completion.bash' >> ~/.zshrc
source ~/.zshrc
Linux 安装 {#linux-安装}
方法一:使用 SDKMAN!(推荐)
# 安装 SDKMAN!
curl -s "https://get.sdkman.io" | bash
source "$HOME/.sdkman/bin/sdkman-init.sh"
# 安装 mvnd
sdk install mvnd
# 验证
mvnd --version
方法二:手动安装
# 下载 mvnd
cd /tmp
wget https://downloads.apache.org/maven/mvnd/1.0-m8/mvnd-1.0-m8-linux-amd64.tar.gz
# 解压到 /opt
sudo tar -xzf mvnd-1.0-m8-linux-amd64.tar.gz -C /opt/
sudo mv /opt/mvnd-1.0-m8-linux-amd64 /opt/mvnd
# 配置环境变量
echo 'export MVND_HOME=/opt/mvnd' | sudo tee -a /etc/profile.d/mvnd.sh
echo 'export PATH=$MVND_HOME/bin:$PATH' | sudo tee -a /etc/profile.d/mvnd.sh
# 重新加载配置
source /etc/profile.d/mvnd.sh
# 验证
mvnd --version
Ubuntu/Debian 特定配置
# 确保安装了必要的依赖
sudo apt-get update
sudo apt-get install -y curl tar gzip
# 配置 Bash 自动补全
echo 'source $MVND_HOME/bin/mvnd-bash-completion.bash' >> ~/.bashrc
source ~/.bashrc
验证安装成功
# 查看版本
mvnd --version
# 查看 Daemon 状态
mvnd --status
# 输出示例(首次运行,无 Daemon):
# No daemons are running
# 执行一次构建后
cd /path/to/your/maven/project
mvnd clean compile
# 再次查看 Daemon 状态
mvnd --status
# 输出示例:
# PID Address Status Last activity Daemon
# 12345 127.0.0.1:12345 Idle 2024-12-08 10:30:15 /path/to/jdk
终端使用 mvnd {#终端使用}
基本命令
mvnd 的命令行参数完全兼容 Maven,只需将 mvn 替换为 mvnd 即可。
# Maven 命令
mvn clean install
# mvnd 命令(完全相同)
mvnd clean install
常用命令对照表
mvnd 特有命令
# 查看 Daemon 状态
mvnd --status
# 输出示例:
# PID Address Status Last activity
# 12345 127.0.0.1:38291 Idle 2024-12-08 10:25:33
# 12346 127.0.0.1:38292 Busy 2024-12-08 10:30:15
# 停止所有 Daemon
mvnd --stop
# 停止指定 Daemon
mvnd --stop 12345
# 查看 mvnd 版本
mvnd --version
# 查看帮助
mvnd --help
实战示例
示例 1:Spring Boot 项目构建
# 克隆项目
git clone https://github.com/spring-projects/spring-boot.git
cd spring-boot
# 首次构建(会启动 Daemon)
time mvnd clean install -DskipTests
# 输出:
# [INFO] ------------------------------------------------------------------------
# [INFO] BUILD SUCCESS
# [INFO] ------------------------------------------------------------------------
# [INFO] Total time: 15.234 s
# real 0m15.521s
# 修改代码后,再次构建(Daemon 已启动,复用 JVM)
time mvnd clean install -DskipTests
# 输出:
# [INFO] ------------------------------------------------------------------------
# [INFO] BUILD SUCCESS
# [INFO] ------------------------------------------------------------------------
# [INFO] Total time: 6.123 s
# real 0m6.245s
# 性能提升:149% !
示例 2:多模块项目增量构建
# 项目结构
my-project/
├── module-core/
├── module-api/
├── module-service/
└── module-web/
# 只构建 module-web 及其依赖
mvnd install -pl module-web -am -DskipTests
# -pl: 指定模块
# -am: also-make,同时构建依赖的模块
# 构建 module-core 及依赖它的所有模块
mvnd install -pl module-core -amd -DskipTests
# -amd: also-make-dependents,同时构建依赖此模块的模块
示例 3:调试模式
# 使用 Maven 的调试模式
mvnd clean install -X
# 输出详细的调试信息
# [DEBUG] ...
示例 4:自定义并行度
# 默认并行度:CPU 核心数 - 1
mvnd clean install
# 指定并行度(4个线程)
mvnd clean install -T 4
# 每个 CPU 核心一个线程
mvnd clean install -T 1C
# 串行构建(禁用并行)
mvnd clean install -T 1
性能监控
# 实时监控 Daemon 状态
watch -n 1 'mvnd --status'
# 查看构建日志(带时间戳)
mvnd clean install | ts '[%Y-%m-%d %H:%M:%S]'
清理 Daemon
# 停止所有空闲的 Daemon
mvnd --stop
# 查看 Daemon 进程
ps aux | grep mvnd
# 强制杀死 Daemon(不推荐,可能导致数据丢失)
pkill -9 -f mvnd
IDEA 集成 mvnd {#idea-集成}
重要说明
⚠️ IDEA 目前不完全原生支持 mvnd
官方 Issue:https://youtrack.jetbrains.com/issue/IDEA-264396
当前状态:IDEA 团队表示 Maven 已达到原生支持,建议使用插件实现
解决方案:使用 Maven Helper 插件
方案一:使用 Maven Helper 插件(推荐)
步骤 1:安装 Maven Helper 插件
1. 打开 IDEA
2. File → Settings (Ctrl+Alt+S)
3. Plugins → Marketplace
4. 搜索 "Maven Helper"
5. 点击 Install
6. 重启 IDEA
步骤 2:配置 mvnd 路径
1. 右键项目根目录
2. Maven Helper → Set Maven Helper Path
3. 填入 mvnd.cmd 的完整路径:
Windows:
D:\tools\mvnd-1.0-m8-windows-amd64\bin\mvnd.cmd
macOS/Linux:
/usr/local/mvnd/bin/mvnd
步骤 3:使用 mvnd 执行构建
方式一:右键项目
1. 右键项目根目录
2. Maven Helper → 选择生命周期
- clean
- compile
- test
- package
- install
方式二:自定义命令
1. 右键项目
2. Maven Helper → Run Maven Goal
3. 输入自定义命令,例如:
clean install -DskipTests
4. 勾选 "Save goal" 保存常用命令
步骤 4:查看已保存的命令
1. File → Settings
2. Tools → Maven Helper
3. 管理已保存的命令(增删改)
方案二:配置 IDEA 的 Maven Runner(部分支持)
⚠️ 注意:此方法并不能让 IDEA 直接使用 mvnd,但可以复用 mvnd 的 Maven 配置。
步骤 1:配置 Maven Home
1. File → Settings (Ctrl+Alt+S)
2. Build, Execution, Deployment → Build Tools → Maven
3. Maven home path: 选择 mvnd 内嵌的 Maven 目录
Windows:
D:\tools\mvnd-1.0-m8-windows-amd64\mvn
macOS/Linux:
/usr/local/mvnd/mvn
步骤 2:配置 settings.xml
User settings file: Override
选择你的 Maven settings.xml 文件
例如:D:\apache-maven-3.9.6\conf\settings.xml
步骤 3:配置本地仓库
Local repository: Override
选择你的本地仓库路径
例如:D:\.m2\repository
步骤 4:配置 Runner
1. Build, Execution, Deployment → Build Tools → Maven → Runner
2. VM Options:
-DarchetypeCatalog=internal
-Dmaven.wagon.http.ssl.insecure=true
-Dmaven.wagon.http.ssl.allowall=true
方案三:使用外部工具配置
步骤 1:创建外部工具
1. File → Settings → Tools → External Tools
2. 点击 "+" 添加新工具
3. 配置如下:
Name: mvnd clean install
Program: D:\tools\mvnd-1.0-m8-windows-amd64\bin\mvnd.cmd
Arguments: clean install -DskipTests
Working directory: $ProjectFileDir$
4. 可以添加多个常用命令
步骤 2:使用外部工具
1. 右键项目根目录
2. External Tools → mvnd clean install
步骤 3:添加快捷键(可选)
1. File → Settings → Keymap
2. 搜索 "External Tools"
3. 找到刚创建的工具
4. 右键 → Add Keyboard Shortcut
5. 设置快捷键,例如:Ctrl+Alt+M
配置 mvnd.properties(统一配置)
为了让 mvnd 和 Maven 使用相同的配置,编辑 mvnd 的配置文件:
# Windows: D:\tools\mvnd-1.0-m8-windows-amd64\conf\mvnd.properties
# macOS/Linux: /usr/local/mvnd/conf/mvnd.properties
# 指定 Maven settings.xml 路径(使用 / 而不是 \)
maven.settings=D:/apache-maven-3.9.6/conf/settings.xml
# 指定本地仓库路径
maven.repo.local=D:/.m2/repository
# 指定 JDK 路径(可选,默认使用 JAVA_HOME)
java.home=D:/Java/jdk-17
# 配置 Daemon 数量
mvnd.maxDaemons=4
# 配置 Daemon 空闲超时(3小时)
mvnd.idleTimeout=3h
# 配置最小堆内存
mvnd.minHeapSize=1g
# 配置最大堆内存
mvnd.maxHeapSize=4g
IDEA 终端中使用 mvnd
在 IDEA 的终端中,可以直接使用 mvnd 命令:
# 打开 IDEA 终端(Alt+F12)
mvnd clean install -DskipTests
# 查看 Daemon 状态
mvnd --status
# 停止 Daemon
mvnd --stop
常见问题解决
问题 1:IDEA 下载依赖报错
错误信息:
java.lang.NoClassDefFoundError: org/slf4j/Logger
解决方案:
从 Maven 的 lib 目录复制以下文件到 mvnd 的 lib 目录:
- slf4j-api-1.7.32.jar
- slf4j-api.license
- maven-slf4j-provider-3.8.4.jar
Windows:
复制到:D:\tools\mvnd-1.0-m8-windows-amd64\mvn\lib\
macOS/Linux:
复制到:/usr/local/mvnd/mvn/lib/
问题 2:Maven Helper 找不到 mvnd
解决方案:
确保 mvnd 路径正确,Windows 下必须指向 mvnd.cmd:
D:\tools\mvnd-1.0-m8-windows-amd64\bin\mvnd.cmd
不是:
D:\tools\mvnd-1.0-m8-windows-amd64\bin\mvnd.exe ❌
问题 3:CPU 占用率过高
现象:使用 mvnd 时 CPU 占用率 80-100%
原因:mvnd 默认使用 CPU核心数-1 进行并行构建
解决方案:
# 限制并行度
mvnd clean install -T 2
# 或在 mvnd.properties 中配置:
mvnd.threads=2
常见问题 {#常见问题}
Q1: mvnd 和 Maven 可以共存吗?
A: 可以完全共存,互不影响。
# 使用 Maven
mvn clean install
# 使用 mvnd
mvnd clean install
# 它们:
# - 可以使用相同的 settings.xml
# - 可以共享同一个本地仓库
# - 完全独立运行
Q2: mvnd 会自动更新吗?
A: 不会。需要手动更新。
# SDKMAN 方式更新
sdk upgrade mvnd
# Homebrew 方式更新
brew upgrade mvnd
# 手动方式:下载新版本,替换旧版本
Q3: mvnd 适合 CI/CD 吗?
A: 不太适合,原因如下:
CI/CD 场景特点:
- 每次都是全新的容器/环境
- 只构建一次就退出
- 无法复用 Daemon
结论:
- mvnd 的优势无法发挥(Daemon 复用)
- 首次启动 Daemon 反而增加时间
- 建议 CI/CD 继续使用 Maven 或 Gradle
例外情况:
如果 CI/CD 环境是长期运行的 Agent(如 Jenkins Slave)
可以考虑使用 mvnd
Q4: Daemon 会一直运行吗?
A: 不会,有超时机制。
# 默认配置(mvnd.properties)
mvnd.idleTimeout=3h # 空闲 3 小时后自动退出
# 可以自定义:
mvnd.idleTimeout=1h # 1 小时
mvnd.idleTimeout=30m # 30 分钟
mvnd.idleTimeout=0 # 永不超时(不推荐)
# 手动停止所有 Daemon
mvnd --stop
Q5: mvnd 占用多少内存?
A: 取决于配置和项目大小。
典型配置:
- Daemon JVM: 1-4GB (可配置)
- GraalVM Client: ~10MB
示例(mvnd.properties):
mvnd.minHeapSize=1g
mvnd.maxHeapSize=4g
Q6: mvnd 能用于 Android 项目吗?
A: 不建议。Android 项目强烈推荐使用 Gradle。
原因:
- Android Gradle Plugin 与 Gradle 深度集成
- mvnd 主要优化 Maven 构建
- AGP 不支持 Maven
Q7: SNAPSHOT 依赖会被缓存吗?
A: 不会。mvnd 特意不缓存 SNAPSHOT 版本。
原因:
- SNAPSHOT 是开发中的版本,经常变化
- 不缓存确保获取最新的 SNAPSHOT
解决方案:
- 本地开发使用:mvnd install
- 依赖其他项目使用:mvnd clean install -U
Q8: 如何卸载 mvnd?
A: 根据安装方式不同:
# SDKMAN 安装
sdk uninstall mvnd
# Homebrew 安装
brew uninstall mvnd
# 手动安装
# 1. 删除安装目录
rm -rf /usr/local/mvnd # macOS/Linux
rd /S /Q D:\tools\mvnd-1.0-m8-windows-amd64 # Windows
# 2. 删除环境变量
# - 从 PATH 中移除 mvnd/bin
# - 删除 MVND_HOME 变量
# 3. 删除配置(可选)
rm -rf ~/.m2/mvnd # 删除 mvnd 的缓存
Q9: mvnd 支持 Maven Wrapper 吗?
A: 不直接支持,但可以结合使用。
# 项目中使用 Maven Wrapper
./mvnw clean install # 使用项目指定的 Maven 版本
# 使用 mvnd
mvnd clean install # 使用 mvnd 内嵌的 Maven
# 建议:
# - 本地开发使用 mvnd
# - CI/CD 使用 Maven Wrapper
Q10: mvnd 与 Gradle 哪个更快?
A: 根据场景而定。
小型项目(<10 模块):
Gradle > mvnd (热启动) > mvnd (首次) > Maven
中型项目(10-50 模块):
mvnd (热启动) ≈ Gradle > mvnd (首次) > Maven
大型项目(>50 模块):
Gradle (配置缓存) > mvnd > Maven
结论:
- Gradle 依然是最快的(尤其是配置缓存)
- mvnd 是 Maven 项目的最佳加速方案
- 如果从零开始,推荐 Gradle
- 如果已有 Maven 项目,使用 mvnd 可以无缝升级
最佳实践 {#最佳实践}
1. 本地开发配置
# ~/.m2/mvnd.properties
# 配置合理的 Daemon 数量(不超过 CPU 核心数-1)
mvnd.maxDaemons=4
# 配置合理的内存
mvnd.minHeapSize=1g
mvnd.maxHeapSize=4g
# 配置合理的超时时间
mvnd.idleTimeout=2h
# 复用 Maven 配置
maven.settings=~/.m2/settings.xml
maven.repo.local=~/.m2/repository
2. 团队协作规范
建议:
1. 统一使用 mvnd 进行本地构建
2. CI/CD 继续使用 Maven
3. 在项目文档中说明 mvnd 的安装和使用
# 项目 README.md 示例
## 快速开始
### 使用 mvnd(推荐)
brew install mvnd@1
mvnd clean install
### 使用 Maven(兼容)
mvn clean install
3. 多项目工作区
# 为不同项目配置不同的 mvnd
# 通过环境变量切换
# 项目 A(使用 JDK 11)
export JAVA_HOME=/path/to/jdk-11
mvnd clean install
# 项目 B(使用 JDK 17)
export JAVA_HOME=/path/to/jdk-17
mvnd clean install
4. 性能调优
# mvnd.properties
# 根据项目大小调整内存
# 小项目(<10 模块)
mvnd.minHeapSize=512m
mvnd.maxHeapSize=2g
# 中型项目(10-50 模块)
mvnd.minHeapSize=1g
mvnd.maxHeapSize=4g
# 大型项目(>50 模块)
mvnd.minHeapSize=2g
mvnd.maxHeapSize=8g
# 并行度调整
# CPU 密集型项目(编译为主)
mvnd.threads=4
# IO 密集型项目(测试为主)
mvnd.threads=8
5. 日常使用技巧
# 创建别名(提高效率)
# ~/.bashrc 或 ~/.zshrc
alias mci='mvnd clean install -DskipTests'
alias mcp='mvnd clean package -DskipTests'
alias mcc='mvnd clean compile'
alias mt='mvnd test'
alias ms='mvnd --status'
alias mx='mvnd --stop'
# 使用示例
mci # 相当于 mvnd clean install -DskipTests
ms # 查看 Daemon 状态
mx # 停止所有 Daemon
6. 脚本自动化
#!/bin/bash
# build.sh - 智能构建脚本
# 检查 mvnd 是否安装
if command -v mvnd &> /dev/null; then
echo "使用 mvnd 构建..."
mvnd clean install -DskipTests
else
echo "mvnd 未安装,使用 Maven 构建..."
mvn clean install -DskipTests
fi
总结 {#总结}
核心要点
✅ mvnd 的优势
构建速度提升 2-10 倍
完全兼容 Maven
无需修改 pom.xml
学习成本极低(只需改命令)
⚠️ mvnd 的局限
首次构建不明显(需要热启动)
不适合 CI/CD(单次构建场景)
IDEA 不完全原生支持
超大项目内存压力大
🎯 适用场景
✅ 本地开发(频繁构建)
✅ 多模块项目
✅ 中小型项目
❌ CI/CD 一次性构建
❌ 超大型项目(100+ 模块)
快速决策树
是否需要频繁构建?
├─ 是 → 使用 mvnd ✅
└─ 否
├─ 是否是 CI/CD?
│ ├─ 是 → 使用 Maven ✅
│ └─ 否 → 根据项目大小决定
│ ├─ 小型项目 → mvnd ✅
│ ├─ 中型项目 → mvnd ✅
│ └─ 超大型项目 → Gradle ✅
推荐配置
最小化配置(开箱即用):
# 安装
brew install mvnd@1 # macOS
sdk install mvnd # 跨平台
# 使用
mvnd clean install
推荐配置(性能优化):
# ~/.m2/mvnd.properties
maven.settings=/path/to/settings.xml
maven.repo.local=/path/to/repository
mvnd.maxDaemons=4
mvnd.minHeapSize=1g
mvnd.maxHeapSize=4g
mvnd.idleTimeout=2h
参考资源
官方文档:https://github.com/apache/maven-mvnd
Maven 官网:https://maven.apache.org/tools/mvnd.html
IDEA 支持请求:https://youtrack.jetbrains.com/issue/IDEA-264396
性能对比:https://github.com/apache/maven-mvnd#benchmarks
结语:mvnd 为 Maven 用户带来了巨大的性能提升,尤其是在本地开发场景。虽然它不是银弹,但对于大多数 Maven 项目来说,迁移成本几乎为零,收益却非常明显。如果你正在使用 Maven,强烈建议试试 mvnd!