425

When I created a Spring Boot application I could see mvnw and mvnw.cmd files in the root of the project. What is the purpose of these two files?

Romil Patel
  • 12,879
  • 7
  • 47
  • 76
shaunthomas999
  • 5,544
  • 2
  • 26
  • 30

6 Answers6

531

These files are from Maven wrapper. It works similarly to the Gradle wrapper.

This allows you to run the Maven project without having Maven installed and present on the path. It downloads the correct Maven version if it's not found (as far as I know by default in your user home directory).

The mvnw file is for Linux (bash) and the mvnw.cmd is for the Windows environment.


To create or update all necessary Maven Wrapper files execute the following command:

mvn -N io.takari:maven:wrapper

To use a different version of maven you can specify the version as follows:

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

Both commands require maven on PATH (add the path to maven bin to Path on System Variables) if you already have mvnw in your project you can use ./mvnw instead of mvn in the commands.

Menuka Ishan
  • 5,164
  • 3
  • 50
  • 66
Dodge
  • 8,047
  • 2
  • 30
  • 45
  • Your answer is very helpful. I check the maven wrapper documentation. I was using `mvn` command for maven operation though I could use `./mvnw` for the same purpose. – shaunthomas999 Aug 02 '16 at 15:30
  • 3
    Thanks for the answer. Can you explain when this gets generated, like is it when you initially create a project? Will it gets updated along the line when you do changes to your pom like add remove dependencies/plugins ? – Asanke Sep 20 '17 at 23:20
  • 2
    and, should you add/commit the mvnw.cmd files? – jpganz18 Jan 15 '19 at 03:26
  • 2
    yes, of course. it allows you to quickly run your maven build without the need to extra install maven or having it on PATH. – Dodge Jan 15 '19 at 19:04
  • 1
    So many thanks for the answer, it's very helpful ¿Could you tell us something about the portability of the maven settings files when we working in that way? Saludos and thanks again. – Daniel Hernández Sep 13 '19 at 04:49
  • 1
    @DanielHernández the maven wrapper uses the default settings.xml on the users system. and according to this [issue](https://github.com/takari/maven-wrapper/issues/4) there are some tricks how you could add a custom settings.xml to the repo but it seems then it ignores the user settings on system. – Dodge Sep 13 '19 at 06:30
37

Command mvnw uses Maven that is by default downloaded to ~/.m2/wrapper on the first use.

URL with Maven is specified in each project at .mvn/wrapper/maven-wrapper.properties:

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

To update or change Maven version invoke the following (remember about --non-recursive for multi-module projects):

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

or just modify .mvn/wrapper/maven-wrapper.properties manually.

To generate wrapper from scratch using Maven (you need to have it already in PATH run:

mvn io.takari:maven:wrapper -Dmaven=3.3.9 
Michal Kordas
  • 10,475
  • 7
  • 58
  • 103
29

The Maven Wrapper is an excellent choice for projects that need a specific version of Maven (or for users that don't want to install Maven at all). Instead of installing many versions of it in the operating system, we can just use the project-specific wrapper script.

mvnw: it's an executable Unix shell script used in place of a fully installed Maven

mvnw.cmd: it's for Windows environment


Use Cases

The wrapper should work with different operating systems such as:

  • Linux
  • OSX
  • Windows
  • Solaris

After that, we can run our goals like this for the Unix system:

./mvnw clean install

And the following command for Batch:

./mvnw.cmd clean install

If we don't have the specified Maven in the wrapper properties, it'll be downloaded and installed in the folder $USER_HOME/.m2/wrapper/dists of the system.


Maven Wrapper plugin

Maven Wrapper plugin to make auto installation in a simple Spring Boot project.

First, we need to go in the main folder of the project and run this command:

mvn -N io.takari:maven:wrapper

We can also specify the version of Maven:

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

The option -N means –non-recursive so that the wrapper will only be applied to the main project of the current directory, not in any submodules.


Source 1 (further reading): https://www.baeldung.com/maven-wrapper

hagrawal7777
  • 14,103
  • 5
  • 40
  • 70
Romil Patel
  • 12,879
  • 7
  • 47
  • 76
  • 14
    Maybe you should mention that part of the text is extracted from https://www.baeldung.com/maven-wrapper – PhoneixS Sep 15 '20 at 11:20
3

short answer: to run Maven and Gradle in the terminal without following manual installation processes.

Gradle example:

./gradlew clean build
./gradlew bootRun

Maven example:

./mvnw clean install
./mvnw spring-boot:run

"The recommended way to execute any Gradle build is with the help of the Gradle Wrapper (in short just “Wrapper”). The Wrapper is a script that invokes a declared version of Gradle, downloading it beforehand if necessary. As a result, developers can get up and running with a Gradle project quickly without having to follow manual installation processes saving your company time and money."

Gradle would also add some specific files corresponding to the Maven files Gradlew and Gradle.bat

Initializer

Jorge Tovar
  • 1,374
  • 12
  • 17
2

In the windows OS, mvnw clean install is used for the maven clean and install activity, and mvnw spring-boot:run is used to run the Spring boot application from Command Prompt.

For Eaxmple:

C:\SamplesSpringBoot\demo>mvnw clean install
C:\SamplesSpringBoot\demo>mvnw spring-boot:run
Carlos Luis Rivera
  • 3,108
  • 18
  • 45
Lova Chittumuri
  • 2,994
  • 1
  • 30
  • 33
-3

By far the best option nowadays would be using a maven container as a builder tool. A mvn.sh script like this would be enough:

#!/bin/bash
docker run --rm -ti \
 -v $(pwd):/opt/app \
 -w /opt/app \
 -e TERM=xterm \
 -v $HOME/.m2:/root/.m2 \
 maven mvn "$@"
André
  • 85
  • 1
  • 5
  • 11
    This does not answer the OP question, it just suggests an alternative – ahmedjaad Aug 30 '18 at 13:16
  • 6
    The very basic idea of maven wrapper is to declare the correct version of maven for this project. And a bonus is avoiding the need to manually install maven. Your approach not only misses to solve the version problem but requires one more locally installed tool. – Max Nov 18 '18 at 21:07
  • 5
    Also note that this mounts the users own local Maven repository into the docker instance. Typically this runs as root, so anything written by the dockerized maven instance is owned by root under Linux. This is not necessarily desirable. I found a properly setup nexus instance accessible to the docker build instance was less painful, especially if you desire reproducible builds. – Thorbjørn Ravn Andersen Dec 07 '18 at 11:51
  • 1
    That was a long ago, but I still prefer this way. About maven version, image tags provide it (just look at the maven page in Docker Hub). As for the root ownership, it just doesn't happen on docker desktop - but indeed happens in linux boxes (and build nodes, of course). A small trick can "force" the current UID in this case (-u argument), so the problem is handled. But all means I find this approach orders of magnitude better. Docker is omnipresent anyway, specially on build nodes. – André Dec 08 '18 at 14:55
  • 1
    (continuing) this approach also has the advantage of reproducing the whole build environment is a very simple way. Old-school Jenkins setups are a nightmare. – André Dec 08 '18 at 14:57
  • 3
    (continuing) Old-school Jenkins setup and mindset lead to this kind of thing. Modern CI/CD tools do the opposite: you just choose a build container. But that's just my opinion. – André Dec 08 '18 at 15:03
  • 5
    I'm not down-voting because the answer could be helpful as an alternative, but it completely misses the point of the OP question and you can't just introduce a complex tool like Docker without even explaining what it is. – dantebarba Feb 01 '19 at 15:15