mvnw和mvnw.cmd文件的目的是什么?


257

当我创建一个Spring Boot应用程序时,我可以在项目的根目录中看到mvnwmvnw.cmd文件。这两个文件的目的是什么?

Answers:


345

这些文件来自Maven包装器。它的工作方式类似于Gradle包装器

这使您可以运行Maven项目,而无需在路径上安装Maven和安装Maven。如果找不到正确的Maven版本,它将下载正确版本(据我所知,默认情况下在您的用户主目录中)。

mvnw文件适用于Linux(bash),mvnw.cmd适用于Windows环境。


要创建或更新所有必需的Maven包装器文件,请执行以下命令:

mvn -N io.takari:maven:wrapper

要使用其他版本的maven,可以如下指定版本:

mvn -N io.takari:maven:wrapper -Dmaven=3.3.3

如果您的项目中已经有mvnw,则可以使用代替命令中的命令,这两个命令都需要打开maven PATH(将maven 的路径添加binPath系统变量上)。./mvnwmvn


您的回答非常有帮助。我检查了Maven包装器文档。我可以使用mvn命令进行Maven操作,尽管我可以将其./mvnw用于相同的目的。
shaunthomas999

2
感谢你的回答。您能解释一下何时生成它,就像最初创建项目时一样吗?当您对pom进行更改(如添加删除依赖项/插件)时,它会沿线更新吗?
Asanke

1
并且,您是否应该添加/提交mvnw.cmd文件?
jpganz18

当然是。它使您可以快速运行maven构建,而无需额外安装maven或将其放在PATH中。
道奇

1
非常感谢您的回答,这非常有用。当您以这种方式工作时,您能告诉我们有关Maven设置文件的可移植性吗?致谢,并再次感谢。
DanielHernández19年

26

Command mvnw使用的Maven在默认情况下~/.m2/wrapper是首次下载到的。

每个项目中都在.mvn/wrapper/maven-wrapper.properties以下位置指定了带有Maven的URL :

distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.3.9/apache-maven-3.3.9-bin.zip

要更新或更改Maven版本,请调用以下命令(--non-recursive对于多模块项目,请记住:):

./mvnw io.takari:maven:wrapper -Dmaven=3.3.9 

或只是.mvn/wrapper/maven-wrapper.properties手动修改。

要使用Maven从头开始生成包装器(您需要先PATH运行它:

mvn io.takari:maven:wrapper -Dmaven=3.3.9 

5

Maven的包装是需要的Maven的(或不希望在所有安装Maven用户)的特定版本的项目的最佳选择。无需在操作系统中安装多个版本,只需使用特定于项目的包装器脚本即可。

mvnw:这是一个可执行的Unix shell脚本,用于代替完全安装的Maven

mvnw.cmd:适用于Windows环境


用例

包装程序应与其他操作系统配合使用,例如:

  • 的Linux
  • OSX
  • 视窗
  • 的Solaris

之后,我们可以针对Unix系统执行以下目标:

./mvnw clean install

并为批处理使用以下命令:

./mvnw.cmd clean install

如果包装属性中没有指定的Maven,则会将其下载并安装在$USER_HOME/.m2/wrapper/dists系统文件夹中。


Maven包装器插件

Maven Wrapper插件可在一个简单的Spring Boot项目中进行自动安装。

首先,我们需要进入项目的主文件夹并运行以下命令:

mvn -N io.takari:maven:wrapper

我们还可以指定Maven的版本:

mvn -N io.takari:maven:wrapper -Dmaven=3.5.2

选项-N表示–non-recursive,因此包装器将仅应用于当前目录的主项目,而不应用于任何子模块。


2

到目前为止,最好的选择是使用Maven容器作为构建器工具。这样的mvn.sh脚本就足够了:

#!/bin/bash
docker run --rm -ti \
 -v $(pwd):/opt/app \
 -w /opt/app \
 -e TERM=xterm \
 -v $HOME/.m2:/root/.m2 \
 maven mvn "$@"

7
这不能回答OP的问题,它只是提出了一种替代方案
ahmedjaad

2
Maven包装器的最基本思想是为该项目声明正确的Maven版本。而且好处是无需手动安装Maven。您的方法不仅错过了解决版本问题的方法,而且还需要另外一个本地安装的工具。
最多

2
还要注意,这会将用户自己的本地Maven存储库安装到docker实例中。通常,它以root身份运行,因此在Linux下,由dockerized maven实例编写的所有内容均归root所有。这不一定是期望的。我发现docker构建实例可访问的正确设置的nexus实例的痛苦较小,尤其是当您需要可复制的构建时。
托尔比约恩Ravn的安徒生

那是很久以前的事了,但我还是更喜欢这种方式。关于Maven版本,图像标签提供了它(只需查看Docker Hub中的Maven页面)。至于根所有权,它只是不会在docker桌面上发生-而是确实发生在linux机器上(当然还有构建节点)。在这种情况下,一个小技巧可以“强制”当前UID(-u参数),因此可以解决问题。但是所有这些都意味着我发现这种方法要好几个数量级。无论如何,Docker无处不在,特别是在构建节点上。
安德烈(André)'18

1
(续)詹金斯的老式设置和思维定势导致了这种情况。现代CI / CD工具的作用与此相反:您只需选择一个构建容器即可。但那只是我的个人意见。
安德烈(André)'18
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.