mvn clean install - a short guide to Maven
Tags: java, maven
Published: 2019-11-20 17:22:21

You can use this guide to understand what a 'mvn clean install' really does. Also: A crash-course on Maven and workarounds for its most common pitfalls.

## What does mvn clean install do?

**The short answer**

[Apache Maven](https://maven.apache.org/) is a popular build tool, that takes your project’s Java source code, compiles it, tests it and converts it into an executable Java program: either a .jar or a .war file.

*mvn clean install* is the command to do just that.

1.  You are calling the *mvn* executable, which means you need Maven installed on your machine. (see [section\_title](#_how_do_you_install_maven))

2.  You are using the *clean* command, which will delete all previously compiled Java sources and resources (like .properties) in your project. Your build will start from a clean slate.

3.  *Install* will then compile, test & package your Java project and even *install*/copy your built .jar/.war file into your local Maven repository. (see [section\_title](#_a_look_at_the_maven_build_lifecycle_phases))

**The (short) long answer:**

There is more to Maven than a couple lines on 'mvn clean install'. If you want to learn about how Maven’s dependency management and build cycle works, or how to avoid the most common pitfalls when working with it: Read on.

## Maven: Crash-Course

[Maven](https://maven.apache.org/) is one of the most popular build tools in the Java universe (others being [Gradle](https://gradle.org/) or old-school [Ant](https://ant.apache.org/)). You can not only build Java projects with it, but pretty much every project written in a
JVM language like [Kotlin](https://kotlinlang.org/) or [Scala](https://www.scala-lang.org/), as well as other languages like C\# and Ruby.

Now what *exactly* does a build tool do? Maven does three things rather well:

1.  **Dependency Management**: Maven lets you easily include 3rd party dependencies (think libraries/frameworks such as Spring) in your project. An equivalent in other languages would be [Javascript’s npm](https://www.npmjs.com/), [Ruby’s gems](https://rubygems.org/) or [PHP’s composer](https://getcomposer.org/).

2.  **Compilation through convention**: In theory you could compile big Java projects with a ton of classes, by hand with the javac command line compiler (or automate that with a bash script). This does however only work for toy projects. Maven expects a certain directory structure for your Java source code to live in and when you later do a *mvn clean install* , the whole compilation and packaging work will be done for you.

3.  **Everything Java**: Maven can also run code quality checks, execute test cases and even deploy applications to remote servers, through plugins. Pretty much every possible task you can think of.

### Maven’s directory layout

#### Maven’s pom.xml

Technically, *any* directory that contains a pom.xml file is also a valid Maven project. A pom.xml file contains everything needed to describe your Java project. Let’s have a look at a minimal version:

```xml
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>

        <groupId>com.marcobehler</groupId>
        <artifactId>my-project</artifactId> 
        <version>1.0-SNAPSHOT</version> 

        <properties>
            <maven.compiler.source>1.8</maven.compiler.source> 
            <maven.compiler.target>1.8</maven.compiler.target>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        </properties>

        <dependencies>
            <dependency> 
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
                <scope>test</scope>
            </dependency>
        </dependencies>
    </project>
```

1.  We are defining a project called 'my-project'

2.  With a version number of 1.0-SNAPSHOT, i.e. work-in-progress

3.  Using Java 1.8 for compilation

4.  With one dependency needed for unit testing: junit in version 4.12

#### Maven’s src & target folders

Apart from a pom.xml file, you also need Java source code for Maven to do its magic, whenever you are calling *mvn clean install*.
By convention:

-   Java source code is to be meant to live in the "/src/main/java" folder

-   Maven will put compiled Java classes into the "target/classes" folder

-   Maven will also build a .jar or .war file, depending on your project, that lives in the "target" folder.

In the end, your project will look like this:

```console
    + myproject
        + -- src
            + -- main
                + -- java
                     MyApp.java
        + -- target
            + -- classes (upon mvn compile)
                 MyApp.class

            myproject.jar (upon mvn package or mvn install)

        pom.xml
```

Now that you have a pom.xml file, as well as a src folder, you still need Maven installed on your machine. Let’s do that now.

### How do you install Maven?

Installing Maven is rather simple. Similar to Java it is just a .zip file that you need to download and put anywhere on your harddrive. The .zip file’s contents look like this:

```console
    Directory c:\dev\apache-maven-3.6.1

    12.07.2019  09:25    <DIR>          .
    12.07.2019  09:25    <DIR>          ..
    12.07.2019  09:25    <DIR>          bin
    12.07.2019  09:25    <DIR>          boot
    12.07.2019  09:25    <DIR>          conf
    12.07.2019  09:25    <DIR>          lib
    12.07.2019  09:24            13.437 LICENSE
    12.07.2019  09:24               182 NOTICE
    12.07.2019  09:24             2.533 README.txt
```

Now you need to make sure to add the /bin directory to your PATH variable, otherwise you cannot call 'mvn' (think: mvn clean install) from anywhere. That’s it.

If you are unsure about any of these two steps, there’s a [great video on Youtube](https://www.youtube.com/watch?v=--Iv5vBIHjI), showing how to install the latest Maven 3.6 on Windows.

### A look at the Maven build lifecycle: phases

Now what *really* happens when you execute a *mvn clean install* in your project? Maven has the concept of a build lifecycle, which is made up of different phases.

Here’s what Maven’s default lifecycle looks like (note: it is missing 'clean').

![Default Maven Lifeycle](https://www.marcobehler.com/images/mavenphasesv3.png "Maven Build Lifecycle: Phases")
These phases are sequential and depend on each other.

**Example**:

When you call "mvn deploy", mvn will also execute *every* lifecycle phase before *deploy*, in order: *validate, compile, test, package, verify, install*.

Same for *verify*: *validate, compile, test, package*. Same for all other phases.

And as 'clean' is not part of Maven’s default lifecycle, you end up with commands like 'mvn clean install' or 'mvn clean package'. 'Install' or 'package' will trigger all preceding phases, but you need to specify clean in addition.

### Where does Maven store 3rd party libraries?

Contrary to other languages, where project dependencies are stored in your project’s directory, Maven has the concept of repositories.

There are local repositories (in your user’s home directory: ~/.m2/) and remote repositories. Remote repositories could be internal, company-wide repositories like [Artifactory](https://jfrog.com/artifactory/) or [Nexus](https://de.sonatype.com/nexus-repository-oss) or the (reference) global repo at <https://repo.maven.apache.org/maven2/>.

Maven will *always* download your project dependencies into your local maven repository *first* and *then* reference them for your build. When you think back at your pom.xml file from before:

```xml
        <dependencies>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
                <scope>test</scope>
            </dependency>
        </dependencies>
```

Then mvn will, once you try and "mvn test" your project, download the junit dependency into ~/.m2/repository/junit/junit/4.12/junit-4.12.jar and reference it via [Java’s classpath mechanism](https://en.wikipedia.org/wiki/Classpath_(Java)) for your build.

For more info on using repositories, see the official documentation at <https://maven.apache.org/guides/introduction/introduction-to-repositories.html>.

## Common Maven Questions

### Where can I find the Maven coordinates for any 3rd party library?

Popular sites are <https://mvnrepository.com/> or <https://search.maven.org/>. You can find others in this thread on [Stackoverflow](https://stackoverflow.com/questions/3430423/recommendable-maven-repository-search-engines).

### What is the difference between mvn clean package and mvn clean install?

If you followed the guide, this should be pretty much clear by now.

-   **clean**: deletes the /target folder. So, the same result for both commands.

-   **package**: Converts your .java source code into a .jar/.war file and puts it into the /target folder.

-   **install**: First, it does a package(!). Then it takes that .jar/.war file and puts it into your local Maven repository, which lives in ~/.m2/repository.

### Why do I need to call 'clean' at all? Wouldn’t mvn install be enough?

In theory, calling 'mvn install' would be enough if Maven was smart enough to do reliable, incremental builds. That means figuring out what Java source files/modules changed and only compile those.

Before Maven 3.1 incremental compilation was basically non-existent, and even with the latest Maven and compiler plugin versions [there’s bugs and documentation issues](https://issues.apache.org/jira/browse/MCOMPILER-209) in the incremental compilation support.

Hence developers got it ingrained to always call 'mvn clean install' (even though this increases build time a lot in bigger projects).

### Mvn clean install does not build sibling projects

Unfortunately, this is something that happens in multi-module projects and other build tools like e.g. Gradle have no problem with it. Imagine your Maven build looks like this:

```console
    + stocks-broker-app (parent)
        + stocks-data-module
        + stocks-rest-module (depends on stock-data)
        + stocks-ui-module (depends on stock-data)
```

and you are doing the following:

```console
    cd stocks-ui-module
    mvn clean install  // or another appropriate goal
```

The problem is: Maven will *NOT* be smart enough to automatically build stock-data as a needed sibling dependency. Instead, you will need to have stock-data built already, yourself.

There’s a workaround though. You don’t always have to build the whole parent project, instead you can specify the list of submodules to build and do a dependent build. In our case, this would look like:

```console
    cd ..  // so you are in the parent project
    mvn -pl stocks-ui-module -am clean install  // or another appropriate goal
```

-   -pl lets you specify the submodules to build

-   -am stands for *also make*, which will build dependent modules as well

### Mvn clean install and snapshot dependencies

Sometimes, if your project depends on SNAPSHOT dependencies, Maven will not update your local Maven repository with the very latest snapshot version.

This is a bit oversimplified, but if you want to make sure that Maven *always* tries to download the latest *snapshot* dependency versions, invoke it with the -U switch.

    mvn -U clean install

### What is mwnw?

Some projects come with a mwnw executable, which *does not* stand for Maven (on) Windows, but rather for Maven *wrapper*.

This means you don’t have to have mvn installed on your machine to build your project - rather, mvn is embedded in your project directory and you can call it with the mvnw executable.

Learn more about the Maven wrapper [here](https://github.com/takari/maven-wrapper).

## Fin

This guide is just a quick overview of what Maven can do for you and how to work around its most common pitfalls. If you want more thorough explanations, check out the [Mastering Maven](https://www.marcobehler.com/courses/23-mastering-maven) course.

If you have any comments or feedback, or want to suggest a another common Maven question, simply leave a comment below.

## There's More Where That Came From

This article originally appeared on www.marcobehler.com/written as part of a series of guides on modern Java programming. To find more guides, visit the website or subscribe to the newsletter to get notified of newly published guides: https://bit.ly/2K0Ao4F.

Thanks for reading.