Maven Commands Cheat Sheet: mvn Examples and Common Errors
Before a commit, a developer runs mvn clean install -DskipTests out of habit and sees BUILD SUCCESS. The check the command was meant to provide never happened: the tests were skipped, yet a jar with untested code is now installed into ~/.m2/repository, and any project that depends on this SNAPSHOT version will pick it up on its next build. The right pre-commit command is mvn verify, and clean is not needed every time — only when target may still hold leftovers of deleted classes.
The mvn command runs Maven from the command line in the form mvn [options] [phases and goals]. A phase (compile, package, verify) runs the lifecycle up to and including itself, a plugin goal written as prefix:goal (dependency:tree) performs a single plugin action without any previous steps, and options (-U, -o, -pl, -D) change how Maven works. Below is a Maven cheat sheet of the mvn commands from the whole module, with links to the detailed lessons, plus a table of common build errors. The examples target Maven 3.9.x.
mvn Syntax: Phases, Goals and Options
A Maven command consists of options and a list of phases and goals, which run from left to right. A phase triggers every earlier phase of its lifecycle, while a goal runs only itself. A goal is written with the plugin prefix (dependency:tree) or with the full coordinates groupId:artifactId[:version]:goal.
| Form | Example | What runs |
|---|---|---|
| Phase | mvn verify | Every default phase from validate to verify |
| Several phases | mvn clean verify | The clean lifecycle, then default up to verify |
| Goal by prefix | mvn dependency:tree | Only the tree goal of maven-dependency-plugin |
| Goal by coordinates | mvn org.apache.maven.plugins:maven-dependency-plugin:3.8.1:tree | The same goal in exactly the given plugin version |
| Phases and goals together | mvn clean compile dependency:tree | Phases first, then the goal — in the order written |
| Plugin parameter | mvn test -Dtest=OrderServiceTest | The test phase; the test property is read by Surefire |
By default Maven resolves short prefixes in the org.apache.maven.plugins and org.codehaus.mojo groups, which is why exec:java and versions:... work without being declared in pom.xml. When a build fails, mvn exits with a non-zero exit code — CI scripts rely on this. The difference between a phase and a goal, with the empty-jar example, is in the section Maven Goals vs Phases; the ways to invoke a plugin are in Plugins and Goals.
Build Commands: clean, package, verify, install
For everyday builds the compile, test, package and verify phases are enough: verify runs all tests and checks and leaves the artifact in target. install is needed only when another project on the same machine must see the artifact, and deploy publishes it to a remote repository.
| Command | What it does and when to use it | More details |
|---|---|---|
mvn clean | Deletes target. Needed after deleting or renaming classes, after changing the JDK or plugin versions, and on CI | Three lifecycles |
mvn compile | Copies resources and compiles src/main/java into target/classes | default phases |
mvn test | Compiles and runs unit tests (Surefire); a failing test stops the build | Surefire and Failsafe |
mvn package | Everything up to and including tests, plus packaging into a jar/war in target | Phase order |
mvn verify | Plus integration tests (Failsafe) and quality checks, if those plugins are configured. The command to run before a commit and on CI | Common build commands |
mvn install | Plus copying the jar and POM into ~/.m2/repository for other projects on this machine. It has nothing to do with installing Maven itself | Installing Maven vs mvn install |
mvn deploy | Plus publishing to the repository from <distributionManagement> (Nexus, Artifactory) | install vs deploy |
mvn site | A project site with reports in target/site (a separate site lifecycle) | The site lifecycle |
mvn clean install | A build "from scratch" with installation into ~/.m2. To check a project, mvn clean verify is usually enough | clean install or verify |
A multi-module project does not need install to connect its modules: within one build the reactor hands each module the results of its siblings directly (Aggregation and the reactor).
Running and Skipping Tests: -DskipTests and -Dtest
To skip tests in Maven, use -DskipTests: the test code is compiled but not run. -Dmaven.test.skip=true does not compile the tests at all and is rarely needed. A single class or method is run with the Surefire parameter -Dtest, a single integration test with the Failsafe parameter -Dit.test.
| Command | What it does and when to use it | More details |
|---|---|---|
mvn package -DskipTests | Tests are compiled but not run; the log shows Tests are skipped. | Common build commands |
mvn package -Dmaven.test.skip=true | Tests are not compiled; no test-jar is produced either, and another module may depend on it | |
mvn verify -DskipITs | Skips only the Failsafe integration tests | Surefire and Failsafe |
mvn verify -Dit.test=OrderRepositoryIT | A single integration test | |
mvn test -Dtest=OrderServiceTest | A single test class | FAQ: a single test |
mvn test -Dtest=OrderServiceTest#create | A single method; several are joined with +: #create+cancel | |
mvn test -Dtest='Order*Test' | By pattern; the quotes stop the shell from expanding * | |
-Dsurefire.failIfNoSpecifiedTests=false | With -Dtest in a multi-module project: modules without a matching test do not fail. The old advice -DfailIfNoTests=false may not work for this case in newer Surefire versions | Reactor options |
mvn verify -Dmaven.test.failure.ignore=true | Tests run, but failures do not stop the build (reports stay in target/surefire-reports) | Surefire and Failsafe |
Running the Application
Maven builds the application, but it is usually easier to run it with the plain java command. For a quick run straight from the sources there is the exec:java goal of exec-maven-plugin (MojoHaus, org.codehaus.mojo): it calls the main method inside the JVM of Maven itself, with the project classpath.
| Command | What it does and when to use it | More details |
|---|---|---|
mvn compile exec:java -Dexec.mainClass=com.examclouds.App | Compiles and runs main; arguments go into -Dexec.args="a b". Without compile the goal uses stale classes from target | Plugin overview |
java -cp target/hello-maven-1.0-SNAPSHOT.jar com.examclouds.App | Runs the app after mvn package with an explicit main class; dependency jars also have to be listed in -cp | First build and run |
java -jar target/hello-maven-1.0-SNAPSHOT.jar | Works only if the manifest has Main-Class, otherwise no main manifest attribute. A regular jar does not contain the dependencies | Executable jar |
Dependencies and Version Updates
Dependency commands come from two plugins: maven-dependency-plugin (tree, analysis, download, local repository cleanup) and versions-maven-plugin from MojoHaus (finding newer versions of libraries and plugins). None of these goals changes pom.xml, except versions:set and the other versions goals that explicitly edit versions.
| Command | What it does and when to use it | More details |
|---|---|---|
mvn dependency:tree | The dependency tree including transitive dependencies — the first thing to check in a version conflict | dependency:tree and analyze |
mvn dependency:tree -Dverbose | Also shows the losing versions (omitted for conflict); support and format depend on the plugin version | |
mvn dependency:tree -Dincludes=com.google.guava | Only the branches with the given library (groupId[:artifactId]) | |
mvn dependency:analyze | Used but undeclared and declared but unused dependencies (a bytecode heuristic) | |
mvn dependency:resolve | Downloads and prints the project dependencies with their scope | Scope |
mvn dependency:go-offline | Downloads dependencies and plugins in advance for working with -o; does not guarantee that everything plugins load during the build is fetched | Local repository |
mvn dependency:purge-local-repository | Removes the project dependencies from ~/.m2 and by default downloads them again — for corrupted files | |
mvn versions:display-dependency-updates | Lists dependencies that have newer versions | dependencyManagement |
mvn versions:display-plugin-updates | The same for plugins, plus plugins without a pinned version | Plugin versions |
mvn versions:set -DnewVersion=1.1-SNAPSHOT | Changes the project version in all modules | Project version |
Diagnostics: the help Plugin
When a build behaves unexpectedly, first check what Maven actually received as input: the effective POM, the settings, the active profiles and the goal bindings. All of this is shown by maven-help-plugin, and none of its goals runs a build.
| Command | What it shows | More details |
|---|---|---|
mvn help:effective-pom | The resulting POM after inheritance, profiles and property interpolation; to a file — -Doutput=effective.xml | Super POM and effective POM |
mvn help:effective-settings | The resulting settings.xml (user + global), passwords masked | settings.xml |
mvn help:active-profiles | Active profiles of each module and where they come from | help:active-profiles |
mvn help:all-profiles | All declared profiles with their activation status | |
mvn help:describe -Dplugin=compiler -Ddetail | Plugin goals and their parameters (with the property names for -D) | Plugin configuration |
mvn help:describe -Dcmd=compile | Which goals are bound to the phases for your packaging | Goal bindings |
mvn help:evaluate -Dexpression=project.version -q -DforceStdout | The value of an expression: the version, project.artifactId, a property from <properties> | Properties |
An example for a build script (the forceStdout parameter exists in maven-help-plugin 3.1.0 and newer):
VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout)
echo "$VERSION"
# Output: 1.0-SNAPSHOT Scripting caveat: help:evaluate without -q
Without -q the VERSION variable receives the whole Maven log with its [INFO] lines, and with -q but without -DforceStdout the value is not printed at all. If the output still contains Downloading lines, add -B -ntp or run the command once beforehand so that the plugin is already in ~/.m2.
Multi-Module Projects
In a multi-module project, commands are run from the root, and a subset of modules is selected with reactor options: -pl picks the modules, -am adds the modules they depend on, and -amd adds the modules that depend on them. Without -am, sibling modules are taken from ~/.m2, that is, in their old version.
| Command | What it does and when to use it | More details |
|---|---|---|
mvn -pl shop-web -am package | The module and everything it depends on | Reactor options |
mvn -pl shop-model -amd verify | The module and everything that depends on it — to check the consumers after a change | |
mvn verify -rf :shop-web | Resume a failed build from a module (Maven suggests this command itself) | |
mvn -pl '!shop-web' verify | All modules except the given one (since Maven 3.2.1) | |
mvn -T 1C verify | Parallel build of independent modules: one thread per CPU core | |
mvn -f shop-web/pom.xml package | Builds the given POM without changing directory; the root reactor is not involved, just as with cd shop-web | Aggregation and the reactor |
mvn -N install | Only the root POM without modules (non-recursive) — for example, to install the parent | Inheritance: parent POM |
Creating a Project and the Maven Wrapper
A new project is created with the archetype:generate goal, and the Maven Wrapper pins the Maven version for the whole team: after mvn wrapper:wrapper the project is built with the ./mvnw script, which downloads the required Maven version by itself.
| Command | What it does and when to use it | More details |
|---|---|---|
mvn archetype:generate -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.5 -DgroupId=com.examclouds -DartifactId=hello-maven -DinteractiveMode=false | A project from the quickstart template without console prompts; in PowerShell, wrap every -D... in quotes | archetype:generate |
mvn wrapper:wrapper | Adds mvnw, mvnw.cmd and .mvn/wrapper/maven-wrapper.properties; the version can be set, for example, with -Dmaven=3.9.11 | Maven Wrapper |
./mvnw clean verify (Windows: mvnw.cmd clean verify) | The same commands and options as mvn, but with the pinned Maven version; the Wrapper does not pin the JDK | |
mvn -v | Maven version, installation path, JDK version and path, OS | Verify the installation |
Useful mvn Options
Options can be written before or after the phases, in any order. The typical set for CI is -B (no interactive prompts and no colored output) and -ntp (no download progress lines): mvn -B -ntp clean verify. The full list is printed by mvn -h.
| Option | Long form | What it does |
|---|---|---|
-U | --update-snapshots | Forces a check for SNAPSHOT updates and discards cached failed download attempts |
-o | --offline | No network: everything needed must already be in ~/.m2 |
-q | --quiet | Errors only |
-X | --debug | Debug output: plugin parameters, classpath, where each file is downloaded from |
-e | --errors | Full exception stack trace on error |
-B | --batch-mode | Non-interactive mode for CI and scripts |
-ntp | --no-transfer-progress | Do not print download progress (since Maven 3.6.1) |
-Dname=value | --define | A user property: overrides POM <properties> and plugin parameters |
-P prod,it | --activate-profiles | Activates profiles; -P '!dev' deactivates one (Profile activation) |
-s / -gs | --settings / --global-settings | A different user / global settings.xml (for example, with a mirror on CI) |
-T 4, -T 1C | --threads | Parallel module build: a number of threads or threads per core |
-N | --non-recursive | Do not build the modules listed in <modules> |
-f path | --file | Use the given POM or directory |
-fae | --fail-at-end | Do not stop at the first failed module: build everything that does not depend on it and fail at the end |
-fn | --fail-never | Never fail the build (see the note below) |
-v / -V | --version / --show-version | Show the version and exit / show the version and continue the build (handy in CI logs) |
Options needed on every run of a project go into the .mvn/maven.config file in the project root (the safest form is one argument per line, for example -ntp and -Dstyle.color=always). JVM settings of Maven itself (memory, encoding) are set with the MAVEN_OPTS environment variable, for example MAVEN_OPTS="-Xmx2g", or in the .mvn/jvm.config file.
Red flag: --fail-never in a CI script
mvn -fn verify ends with BUILD SUCCESS and exit code 0 even if modules failed to compile or their tests failed: the failure is visible only in the Reactor Summary. A CI script treats such a build as green. If you want to see the errors of all modules at once, use -fae: the build runs to the end but still fails.
Common Maven Build Errors and How to Fix Them
Almost every Maven build error starts with a [ERROR] Failed to execute goal line or with a POM reading error before the build begins. The first line already contains the essentials: which plugin and goal failed, in which module, and why. More details come from a rerun with -e (exception stack trace) and -X (debug log).
An example (approximate form for Maven 3.9.x; the path and line number depend on the project):
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.13.0:compile (default-compile) on project shop-web: Compilation failure
[ERROR] /home/user/shop/shop-web/src/main/java/com/examclouds/web/App.java:[12,9] cannot find symbol
...
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging. How to read it: maven-compiler-plugin:3.13.0:compile is the plugin, its version and the goal; (default-compile) is the execution id: the default- prefix means the standard binding to a phase, default-cli means the goal was called from the command line, and any other name is an execution from your pom.xml; on project shop-web is the module; after the colon comes the cause. The following lines refine the cause, and in a multi-module build the end of the log suggests -rf :shop-web. The messages in the table below are shortened; the exact wording depends on the Maven and plugin versions.
| Message or symptom | Cause | Fix |
|---|---|---|
'mvn' is not recognized as an internal or external command, operable program or batch file. (cmd), mvn: command not found | The Maven bin directory is not on the PATH, or the terminal was opened before the variables were changed | Add bin to PATH and open a new terminal (installation errors) |
The JAVA_HOME environment variable is not defined correctly | JAVA_HOME points to bin or to a path that does not exist | JAVA_HOME = the JDK root (installation errors) |
... requires a project to execute but there is no POM in this directory | The command was run outside the directory with pom.xml | cd into the project root or use -f path/pom.xml (first project) |
Could not resolve dependencies ... Could not find artifact com.examclouds:shop-core:jar:1.0-SNAPSHOT | A typo in the coordinates; the artifact exists only in someone's local ~/.m2; the corporate repository is not configured; a sibling module is built from a subdirectory | Check the GAV, configure the repository, build modules from the root with -pl ... -am (repository errors) |
... was cached in the local repository, resolution will not be reattempted until the update interval ... | Maven remembered a failed download | Fix the cause and run with -U (How Maven resolves a dependency) |
501 HTTPS Required; Blocked mirror for repositories: [...] | A repository URL over HTTP: Maven Central has been HTTPS-only since 2020, and Maven 3.8.1+ blocks external HTTP repositories (maven-default-http-blocker) | Replace http:// with https:// in pom.xml and settings.xml (current versions) |
Source option 7 is no longer supported. Use 8 or later.; release version 25 not supported | Outdated source/target from an old archetype; the JDK running Maven is older than release | maven.compiler.release instead of source/target; check the JDK in mvn -v (minimal pom.xml) |
package org.junit.jupiter.api does not exist on mvn compile | A test sits in src/main/java, or the main code uses a library with scope = test | Move the class to src/test/java or fix the scope (Scope) |
NoSuchMethodError / NoClassDefFoundError at runtime, the build passes | A version conflict: Maven kept one version of the library by the nearest-wins rule | dependency:tree -Dverbose, an explicit version or exclusions (Version conflicts) |
no main manifest attribute, in target/...jar | The jar manifest has no Main-Class | Configure maven-jar-plugin or run with java -cp (Executable jar) |
Non-resolvable parent POM ... | The parent was found neither via relativePath nor in the repositories | Check <relativePath> and the parent GAV, or build from the root (parent POM) |
The projects in the reactor contain a cyclic reference | Two modules depend on each other | Move the shared code into a separate module (Dependencies between modules) |
No plugin found for prefix '...' | The artifactId was used instead of the prefix (maven-checkstyle-plugin:check), or the plugin is not from the standard groups | Use the short prefix (checkstyle:check) or the full coordinates (How to run a plugin) |
Tests do not run: Tests run: 0 or no test block at all | The class name does not match the Surefire patterns (*Test and others); *IT without Failsafe; a very old Surefire (before 2.22.0) does not see JUnit 5 | Rename the class, add Failsafe, upgrade Surefire (Surefire and Failsafe) |
Unknown lifecycle phase ".examclouds" | PowerShell split the -DgroupId=com.examclouds argument | Wrap every -D... in quotes (first project) |
OutOfMemoryError: Java heap space, slow build | Not enough memory for the Maven JVM or the test JVM; an unnecessary clean, update checks on every run | MAVEN_OPTS="-Xmx2g" for Maven, argLine for tests (note below); -T 1C; clean only when needed |
Worth knowing: MAVEN_OPTS does not reach your tests
By default Surefire runs tests in a separate JVM (fork), and MAVEN_OPTS does not apply to it: if an OutOfMemoryError is thrown inside a test, raising -Xmx in MAVEN_OPTS changes nothing. Memory for the test JVM is set with the Surefire parameter argLine: mvn test -DargLine="-Xmx1g" or <argLine> in the plugin configuration. MAVEN_OPTS is for the cases when Maven itself runs out of memory — during compilation or in a large reactor.
Frequently Asked Questions
Which command should CI run: mvn clean install or mvn clean verify?
For pull request checks — mvn -B -ntp clean verify: all tests and checks run, and the local repository of the agent is not cluttered. install is needed only if the next step builds another project that needs this artifact from ~/.m2; to publish to Nexus or Artifactory, use deploy. More details are in the section Common Build Commands.
How do I skip tests in Maven?
Usually with -DskipTests: the tests are compiled but not run. -Dmaven.test.skip=true also skips compiling the tests, so errors in the test code go unnoticed. -DskipITs skips only the integration tests. All the variants are in the table of the section Running and Skipping Tests.
How do I force Maven to update a SNAPSHOT dependency?
Run the build with the -U option: Maven checks all remote repositories for SNAPSHOT updates without waiting for the update interval (once a day by default) and forgets cached failed downloads. If the files in ~/.m2 are corrupted, mvn dependency:purge-local-repository helps.
How do I get the project version from the command line?
With mvn help:evaluate -Dexpression=project.version -q -DforceStdout — it prints only the value, for example 1.0-SNAPSHOT, and is suitable for scripts. The version of Maven itself and of the JDK is shown by mvn -v. A script example is in the section Diagnostics.
Why does Maven download dependencies on every build?
Most often the local repository is empty every time: a CI agent or a Docker container starts without ~/.m2 (cache that directory), or the command sets -Dmaven.repo.local to a temporary path. If the log shows only maven-metadata.xml, Maven is checking for SNAPSHOT updates — this happens when -U is used on every run. Offline builds work with -o once everything needed has been downloaded.
Comments