Maven command line
last modified November 8, 2026
In this article we cover the options of the mvn command. We show
how to build selected modules of a multi-module project, handle failures,
run parallel and offline builds, control the output, and store default
options in the project. The examples use Maven 3.10 and Java 25.
The general form of the command is
mvn [options] [goals and phases]. Options start with a dash,
for instance -q or --quiet; most of them have a
short and a long form. The mvn --help command lists all of them.
Phases and goals
A phase is a step of a lifecycle, such as compile or
package. Running a phase runs all earlier phases of its
lifecycle. Phases from different lifecycles can be combined:
mvn clean package runs the clean lifecycle and then
the default lifecycle up to package.
A goal is a single task of a plugin. It is written as
prefix:goal, for example compiler:compile, or with
full coordinates as groupId:artifactId:version:goal. The full
form runs an exact plugin version without any configuration in the POM.
Both commands print the project version. The short form resolves the
help prefix to the Maven Help Plugin and uses the version
configured in the POM, or the latest release if there is none. The
-N option is explained below.
$ mvn -q org.apache.maven.plugins:maven-help-plugin:3.5.2:evaluate \ -Dexpression=project.version -DforceStdout -N 1.0.0 $ mvn -q help:evaluate -Dexpression=project.version -DforceStdout -N 1.0.0
The example project
Most options are useful in multi-module projects. Our shop project has four
modules: common with a Money record,
orders and reports, which both use
common, and app, which uses orders.
Each module except app has one unit test.
shop ├── common Money ├── reports Report → common ├── orders Order → common └── app App → orders
The POM files
The root POM is the parent and aggregator of the modules.
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>shop</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<modules>
<module>common</module>
<module>reports</module>
<module>orders</module>
<module>app</module>
</modules>
<properties>
<maven.compiler.release>25</maven.compiler.release>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.junit</groupId>
<artifactId>junit-bom</artifactId>
<version>6.1.3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.16.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.6.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.5.1</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
The parent sets the Java release, adds JUnit 6 to all modules for testing, and pins the plugin versions.
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.example</groupId>
<artifactId>shop</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>orders</artifactId>
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>common</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>
The module POMs inherit from the root POM and declare dependencies on other modules. The other module POMs look the same.
package com.example.reports;
import com.example.common.Money;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
class ReportTest {
@Test
void formatsLine() {
var expected = Boolean.getBoolean("broken") ? "broken" : "Sales 100.00 EUR";
assertEquals(expected, Report.line("Sales", Money.of("100.00")));
}
}
The test of the reports module fails on purpose when the
broken system property is set. Surefire passes properties given
on the Maven command line to the test JVM, so -Dbroken=true lets
us simulate a failing module.
Building all modules
Without options, Maven builds all modules. The reactor sorts them so that
every module comes after its dependencies; the order of
reports and orders follows their order in the
modules element.
$ mvn package [INFO] Reactor Build Order: [INFO] shop [pom] [INFO] common [jar] [INFO] reports [jar] [INFO] orders [jar] [INFO] app [jar] [INFO] Reactor Summary for shop 1.0.0: [INFO] shop ............................................... SUCCESS [ 0.002 s] [INFO] common ............................................. SUCCESS [ 2.049 s] [INFO] reports ............................................ SUCCESS [ 0.680 s] [INFO] orders ............................................. SUCCESS [ 0.593 s] [INFO] app ................................................ SUCCESS [ 0.064 s] [INFO] BUILD SUCCESS ... $ java -cp app/target/app-1.0.0.jar:orders/target/orders-1.0.0.jar:common/target/common-1.0.0.jar \ com.example.app.App Order total: 24.50 EUR
Selecting modules with -pl
The -pl (--projects) option builds only the given
modules. Modules are given by their directory, by
:artifactId, or by groupId:artifactId, separated by
commas. An exclamation mark, or a minus sign, excludes a module; in Bash the
argument must be quoted, otherwise the shell interprets the exclamation
mark.
The first two builds succeed, because all the needed modules are part of
the build. The third fails: app needs orders and
common, which are not in the build and not in the local
repository. In Maven 3, a module outside the build is resolved like any other
dependency.
$ mvn package -pl common,reports [INFO] common ............................................. SUCCESS [ 2.220 s] [INFO] reports ............................................ SUCCESS [ 0.680 s] [INFO] BUILD SUCCESS ... $ mvn package -pl '!reports' [INFO] shop ............................................... SUCCESS [ 0.002 s] [INFO] common ............................................. SUCCESS [ 1.746 s] [INFO] orders ............................................. SUCCESS [ 1.118 s] [INFO] app ................................................ SUCCESS [ 0.060 s] [INFO] BUILD SUCCESS ... $ mvn package -pl app [ERROR] BUILD FAILURE [ERROR] Failed to execute goal on project app: Could not resolve dependencies for project com.example:app:jar:1.0.0 [ERROR] dependency: com.example:orders:jar:1.0.0 (compile) ...
Also make with -am
The -am (--also-make) option adds the modules that
the selected modules depend on. This is the usual way to build one module of
a large project.
Maven built app together with orders and
common, and the parent POM. The reports module was
left out.
$ mvn package -pl :app -am [INFO] shop ............................................... SUCCESS [ 0.002 s] [INFO] common ............................................. SUCCESS [ 2.066 s] [INFO] orders ............................................. SUCCESS [ 0.719 s] [INFO] app ................................................ SUCCESS [ 0.068 s] [INFO] BUILD SUCCESS ...
Also make dependents with -amd
The -amd (--also-make-dependents) option works in
the other direction: it adds the modules that depend on the selected modules.
After a change in common, this command rebuilds and tests
everything that may be affected by the change.
$ mvn package -pl common -amd [INFO] common ............................................. SUCCESS [ 2.092 s] [INFO] reports ............................................ SUCCESS [ 0.801 s] [INFO] orders ............................................. SUCCESS [ 0.609 s] [INFO] app ................................................ SUCCESS [ 0.088 s] [INFO] BUILD SUCCESS ...
Failure handling
By default, Maven stops at the first module that fails; this is the
-ff (--fail-fast) mode. The modules after it are
skipped, even those that do not depend on the failed module.
The orders and app modules were skipped, although
they do not depend on reports. Maven suggests the
-rf option to resume the build.
$ mvn package -Dbroken=true [INFO] Reactor Summary for shop 1.0.0: [INFO] orders ............................................. SKIPPED [INFO] app ................................................ SKIPPED [INFO] shop ............................................... SUCCESS [ 0.002 s] [INFO] common ............................................. SUCCESS [ 2.142 s] [ERROR] reports ............................................ FAILURE [ 0.680 s] [ERROR] BUILD FAILURE [ERROR] After correcting the problems, you can resume the build with the command [ERROR] mvn <args> -rf :reports
Fail at end and fail never
With -fae (--fail-at-end), Maven continues with the
modules that do not depend on a failed module and reports the failure at the
end. With -fn (--fail-never), it also reports
failures, but the build always ends with exit status 0.
The -fae option is useful on CI servers, where we want to see
all failures of a build at once. The -fn option hides failures
from scripts, so it should be used with care.
$ mvn package -Dbroken=true -fae [INFO] shop ............................................... SUCCESS [ 0.002 s] [INFO] common ............................................. SUCCESS [ 2.021 s] [INFO] orders ............................................. SUCCESS [ 0.692 s] [INFO] app ................................................ SUCCESS [ 0.052 s] [ERROR] reports ............................................ FAILURE [ 0.680 s] [ERROR] BUILD FAILURE ... $ mvn package -Dbroken=true -fn [INFO] shop ............................................... SUCCESS [ 0.002 s] [INFO] common ............................................. SUCCESS [ 1.551 s] [INFO] orders ............................................. SUCCESS [ 0.485 s] [INFO] app ................................................ SUCCESS [ 0.015 s] [ERROR] reports ............................................ FAILURE [ 0.565 s] [ERROR] BUILD FAILURE [INFO] Build failures were ignored. $ echo $? 0
Resuming with -rf
The -rf (--resume-from) option starts the build at
the given module and builds it and all modules after it in the reactor
order.
The resumed build fails. The common module comes before
reports, so it is not part of the build, and Maven 3 looks for
it in the local repository. Resuming works when the earlier modules were
installed with mvn install; with mvn package, we
must rebuild them, for instance with -pl reports -am.
$ mvn package -rf :reports [INFO] reports [jar] [INFO] orders [jar] [INFO] app [jar] [ERROR] BUILD FAILURE [ERROR] Failed to execute goal on project reports: Could not resolve dependencies for project com.example:reports:jar:1.0.0 [ERROR] dependency: com.example:common:jar:1.0.0 (compile) ...
Parallel builds
The -T (--threads) option builds independent
modules in parallel. The value is a number of threads, such as
-T 4, or a multiple of the CPU cores, such as -T 1C.
Here reports and orders can be built at the same
time, because both need only common. Parallel builds help in
projects with many independent modules; all plugins used in the build must be
thread-safe, and Maven warns about those that are not.
$ mvn package -T 4 [INFO] Using the MultiThreadedBuilder implementation with a thread count of 4 [INFO] shop ............................................... SUCCESS [ 0.002 s] [INFO] common ............................................. SUCCESS [ 2.019 s] [INFO] reports ............................................ SUCCESS [ 0.878 s] [INFO] orders ............................................. SUCCESS [ 0.947 s] [INFO] app ................................................ SUCCESS [ 0.064 s] [INFO] BUILD SUCCESS ...
Controlling the output
The -q (--quiet) option shows only errors, so a
successful build prints nothing. The -X (--debug)
option prints debug output, including the effective configuration of every
plugin goal; it is long, so we show only the beginning.
Other output options:
-e(--errors) — prints the full stack trace of an error-B(--batch-mode) — non-interactive mode without colours; used on CI servers-ntp(--no-transfer-progress) — hides download progress-l file(--log-file) — writes the output to a file-v(--version) — prints the versions of Maven and Java
The -N (--non-recursive) option, used in the debug
example, builds only the project in the current directory, not its modules.
$ mvn -q package $ mvn -X validate -N | head -6 Apache Maven 3.10.0 (c43a36b8d67be7e0805a411bc0898af1a51f5472) Maven home: /home/user/.sdkman/candidates/maven/current Java version: 25.0.3, vendor: Amazon.com Inc., runtime: /home/user/.sdkman/candidates/java/25.0.3-amzn Default locale: en, platform encoding: UTF-8, time zone: Europe/Bratislava OS name: "linux", version: "6.8.0-138-generic", arch: "amd64", family: "unix" [DEBUG] Created lock factory selector; available lock factories [file-lock, rwlock-local, semaphore-local, noop]
Properties
The -D option sets a property: -Dname=value, or
-Dname for the value true. Plugins read many of
their parameters from such properties. A common example is skipping tests.
The skipTests property compiles the tests but does not run them.
The maven.test.skip property skips the compilation of the tests
too. In most cases skipTests is the better choice; with
maven.test.skip, test JARs are not built, so a module that uses
the test classes of another module can fail.
$ mvn package -pl common -DskipTests [INFO] --- compiler:3.16.0:testCompile (default-testCompile) @ common --- [INFO] Compiling 1 source file with javac [debug release 25] to target/test-classes [INFO] --- surefire:3.6.1:test (default-test) @ common --- [INFO] Tests are skipped. ... $ mvn package -pl common -Dmaven.test.skip=true [INFO] --- compiler:3.16.0:testCompile (default-testCompile) @ common --- [INFO] Not compiling test sources [INFO] --- surefire:3.6.1:test (default-test) @ common --- [INFO] Tests are skipped. ...
Offline and update options
The -o (--offline) option forbids network access.
Maven uses only the artifacts already in the local repository. This is
handy without a network connection and on build servers that must not
download anything. To demonstrate it, we use a second small project.
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
<version>1.11.0</version>
</dependency>
</dependencies>
The project depends on commons-text 1.11.0, a version that was
never downloaded to our local repository.
In offline mode, Maven fails and tells us which artifact is missing. The
dependency:go-offline goal downloads everything a project needs
in advance. The opposite option, -U
(--update-snapshots), makes Maven check the remote repositories
for newer snapshot versions and refresh the cached metadata, instead of
waiting for the daily update.
$ mvn -o compile [ERROR] BUILD FAILURE [ERROR] Failed to execute goal on project offline: Could not resolve dependencies for project com.example:offline:jar:1.0.0 [ERROR] dependency: org.apache.commons:commons-text:jar:1.11.0 (compile) [ERROR] Cannot access central (https://repo.maven.apache.org/maven2) in offline mode and the artifact org.apache.commons:commons-text:jar:1.11.0 has not been downloaded from it before. ...
The .mvn/maven.config file
Options that a project always needs can be stored in the
.mvn/maven.config file in the root directory of the project. Maven
reads it on every run and adds its contents to the command line. Since
Maven 3.9, each option must be on its own line. The
.mvn/jvm.config file holds options for the JVM that runs Maven.
The -DskipTests option from maven.config skipped the
tests, although we did not type it. The system property from
jvm.config is visible to Maven like any other property. Both
files belong to the project and are committed to version control, so all
developers and the CI server get the same defaults. For personal settings,
the MAVEN_OPTS environment variable passes options to the JVM.
$ cat .mvn/maven.config --batch-mode --no-transfer-progress -DskipTests $ cat .mvn/jvm.config -Xmx512m -Dbuild.env=ci $ mvn package -pl common [INFO] --- surefire:3.6.1:test (default-test) @ common --- [INFO] Tests are skipped. [INFO] BUILD SUCCESS ... $ mvn -q help:evaluate -Dexpression=build.env -DforceStdout -N ci
The MAVEN_ARGS variable
Since Maven 3.9, the MAVEN_ARGS environment variable holds
options that are added to every mvn command. It is meant for
personal defaults, such as -ntp, that should not be committed
to the project.
The options from the variable selected the app module and its
dependencies, as if we typed -pl app -am.
$ MAVEN_ARGS="-pl app -am" mvn package [INFO] shop ............................................... SUCCESS [ 0.002 s] [INFO] common ............................................. SUCCESS [ 2.140 s] [INFO] orders ............................................. SUCCESS [ 0.742 s] [INFO] app ................................................ SUCCESS [ 0.053 s] [INFO] BUILD SUCCESS ...
Summary of options
| Option | Long form | Meaning |
|---|---|---|
-pl | --projects | build only the given modules |
-am | --also-make | also build the dependencies of the selected modules |
-amd | --also-make-dependents | also build the modules that depend on the selected modules |
-rf | --resume-from | resume the build from a module |
-N | --non-recursive | do not build the modules |
-f | --file | use another POM file or directory |
-fae | --fail-at-end | continue with independent modules after a failure |
-fn | --fail-never | never fail the build |
-T | --threads | build modules in parallel |
-o | --offline | work offline |
-U | --update-snapshots | check for updated snapshots |
-D | --define | set a property |
-P | --activate-profiles | activate or deactivate profiles |
-s | --settings | use another user settings.xml file |
-q | --quiet | show only errors |
-X | --debug | show debug output |
-e | --errors | show stack traces of errors |
-B | --batch-mode | run non-interactively |
-ntp | --no-transfer-progress | hide download progress |
Source
In this article we have covered the most useful options of the Maven command line.
Author
List all Java tutorials.