Maven: Configuring Maven
|
This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production. The reference material consulted while preparing these pages is listed in the section bibliography. |
This page is written against Apache Maven 3.10.0 (released on 27 September 2026), with Maven 3.9.16 and Maven 4.0.0-rc-7 (a
release candidate) run wherever they differ. Every example marked as run was executed on JDK 26 on 2026-10-16, on macOS (Apple
silicon), in a scratch copy of the tidepool build: a parent POM with one module and nothing else. Output that comes from a
run is shown as printed, except that the scratch paths are shortened to <project> and <lab> and that lines are removed with
grep where the text says so. Anything that could not be run here (Windows, a package manager, a real corporate proxy) is
labelled "not run here".
Maven is configured in two different senses, and the two are easy to confuse. A project is configured by its POM, which says what
to build and is the same for everybody. Maven itself is configured by files and variables that say how this machine, this user
or this checkout runs Maven: how much memory the JVM gets, which options every command receives, which extensions are loaded,
where the local repository is. This page is about the second kind. The POM is on
POM Fundamentals, the command-line options on
Running Maven (CLI), and settings.xml (servers, mirrors,
proxies, profiles) on
settings.xml & Password Encryption.
Installing Maven and the JAVA_HOME question are on Installation.
The running scenario is described on the section landing page; for the
other two tools see Ant: Properties
and Gradle.
Where Maven reads its configuration
The official page lists the places in one paragraph each. Put into one table, with the level at which each applies:
| Place | Level | What it carries | Travels with the project? |
|---|---|---|---|
|
Shell or machine |
JVM options for the JVM that runs Maven, such as heap size or |
No |
|
Shell or machine |
Command-line arguments inserted before the ones typed. |
No |
|
Machine or user |
Shell commands run by the launcher script, normally to set the two variables above or |
No |
|
User and installation |
Local repository, servers, mirrors, proxies, profiles. |
No |
|
Project (checkout) |
Command-line arguments, one per line. |
Yes |
|
Project (checkout) |
JVM options for Maven. |
Yes |
|
Project (checkout) |
Core extensions loaded before the build starts. |
Yes |
|
User and installation |
Core extensions for every build. |
No |
The rule of thumb is the one in the table’s last column. Whatever every contributor and the CI server must share belongs in
.mvn, committed with the code. Whatever is personal or tied to a machine (a JDK location, a proxy, a mirror, credentials)
belongs in the environment, a mavenrc file or settings.xml. The directory layout of the installation, where conf/ lives,
is on Installation.
Source: Maven: Configuring Apache Maven
Source: Maven guide: Configuring Maven
The scratch project used on this page
All the runs below read one value, a user property called who, with the Help plugin’s evaluate goal. The helper function is
the whole of the tooling: mvn stands for the Maven under test and -q -N -DforceStdout print only the value, without running
the modules.
ev() {
mvn -q -N org.apache.maven.plugins:maven-help-plugin:3.5.2:evaluate \
-Dexpression="$1" -DforceStdout "${@:2}"
echo
}
The project is a parent POM (io.tidepool:tidepool-parent, packaging pom) with one module app, and a .mvn directory next
to the parent POM. With no configuration at all the property is not set, which evaluate reports:
ev who
null object or invalid expression
Each section below sets who in a different place and shows what Maven sees.
This helper function and project are this page’s own lab setup, not an example from the Maven documentation.
MAVEN_OPTS
MAVEN_OPTS holds options for the Java Virtual Machine that runs Maven. The official page gives the example of memory
settings, -Xms256m -Xmx512m. It is read by the launcher script and passed to java before the main class, so it accepts any
JVM option, including -D system properties. To make the effect visible, ask the JVM to print its flags and keep the line that
shows the maximum heap size:
MAVEN_OPTS="-Xmx512m -XX:+PrintFlagsFinal" ev project.artifactId | grep -w MaxHeapSize
size_t MaxHeapSize = 536870912 {product} {command line}
That is 512 MiB, and the flag came from the command line. The run used Maven 3.10.0; 3.9.16 and 4.0.0-rc-7 print the same value.
MAVEN_OPTS affects the JVM that runs Maven, not the JVMs Maven starts to run tests, which are configured on the Surefire plugin
(Testing with Surefire), and not the compiler.
MAVEN_ARGS
Since Maven 3.9.0, MAVEN_ARGS carries arguments that are passed to Maven before the ones typed on the command line. The
official example is -B -V checkstyle:checkstyle: options and even goals. It suits a CI server that should always run in batch mode,
without having to edit each job. The next section shows how it ranks against the other sources of arguments; for now, one
property set in MAVEN_ARGS while .mvn/maven.config (below) also sets it:
cat .mvn/maven.config
ev who
MAVEN_ARGS="-Dwho=args" ev who
-Dwho=config
config
args
MAVEN_ARGS wins over maven.config. The same three results came out of Maven 3.9.16, 3.10.0 and 4.0.0-rc-7.
The mavenrc files
The launcher script sources /usr/local/etc/mavenrc, /etc/mavenrc and ~/.mavenrc (in that order) before it looks for Java,
unless MAVEN_SKIP_RC is set. The official page describes .mavenrc as defining "environment variables used when Maven builds
the project". On Windows the file is %USERPROFILE%\mavenrc_pre.cmd for Maven 3 and %USERPROFILE%\mavenrc.cmd for Maven 4
(not run here). The use of the file to choose a JDK is shown on
Installation; here it sets the two variables of the previous
sections. A scratch home directory holds this .mavenrc:
export MAVEN_OPTS="-Xmx700m -XX:+PrintFlagsFinal"
export MAVEN_ARGS="-Dwho=mavenrc"
HOME=<lab>/home ev who | grep -w "MaxHeapSize\|mavenrc"
MAVEN_SKIP_RC=1 HOME=<lab>/home ev who
size_t MaxHeapSize = 738197504 {product} {command line, ergonomic}
mavenrc
config
The first run took the heap size (700 MiB, rounded up by the JVM) and the property from the file. The second, with
MAVEN_SKIP_RC set, ignored the file, and who came from maven.config again. Two details of this run matter.
mavenrc is plain shell, so it needs export, and it is read by the launcher script, not by Java: the run changed the
shell variable HOME, which the script uses, and that is the reason it worked. Java finds the user’s home directory in another way, as
the section on the local repository shows.
The .mvn directory
A directory called .mvn at the top of the project is the project-level configuration. The official page says it "may be
checked into version control". It holds up to three files, all optional: maven.config, jvm.config and extensions.xml. Maven 4
adds more, listed at the end of this section. The same directory also holds wrapper/ when the project uses the Maven Wrapper
(Maven Wrapper), and the quickstart archetype of
Getting Started now generates a .mvn directory
with a jvm.config and a maven.config.
How the directory is found
The launcher script looks for .mvn starting in the current directory and moving up through the parents, until it finds one. Running
a command inside a module therefore still uses the .mvn of the multi-module root. With -f, the lookup starts from the POM that
is named:
cd app && ev who
cd / && ev who -f <project>/pom.xml
Apache Maven 3.10.0 (c43a36b8d67be7e0805a411bc0898af1a51f5472)
Maven home: <scratch>/tools/apache-maven-3.10.0
Java version: 26, vendor: Oracle Corporation, runtime: /Library/Java/JavaVirtualMachines/jdk-26.jdk/Contents/Home
Default locale: es_ES, platform encoding: UTF-8, time zone: Europe/Madrid
OS name: "mac os x", version: "27.0.1", arch: "aarch64", family: "mac"
config
Apache Maven 3.10.0 (c43a36b8d67be7e0805a411bc0898af1a51f5472)
Maven home: <scratch>/tools/apache-maven-3.10.0
Java version: 26, vendor: Oracle Corporation, runtime: /Library/Java/JavaVirtualMachines/jdk-26.jdk/Contents/Home
Default locale: es_ES, platform encoding: UTF-8, time zone: Europe/Madrid
OS name: "mac os x", version: "27.0.1", arch: "aarch64", family: "mac"
config
In both cases the value config comes from the root .mvn/maven.config. The five version lines are there because that file
contains -V (see below), not because of the -q of the helper. Maven 3.9.16 and 4.0.0-rc-7 found the file in the same two
situations (the value was config in all three; the version lines are not repeated). Maven 4 also uses the directory
as the marker of the project root; without one it prints the warning described on
Getting Started.
maven.config
maven.config holds command-line arguments that are added to every run. The official page gives -T3 -U --fail-at-end as an example.
Since Maven 3.9.0 each argument goes on a line of its own, and lines that begin with # are comments; Maven 3.8.x and older
did not support comments (not run here, there is no such Maven on this machine). A file that uses an option together with its value
must also keep them on separate lines when the option takes a separate value. Here is the file that the run in the previous
section read:
# defaults for every build of this project
-B
-V
-T
2
-Dwho=config
-B is batch mode, -V prints the version first, and -T followed by 2 on the next line is the same as -T 2: two build
threads. Running without -q shows all three at work. Only lines that the grep below removes (the plugin prefix lookups,
which differ on a cold local repository) were left out; the output is from Maven 3.10.0:
mvn -N org.apache.maven.plugins:maven-help-plugin:3.5.2:evaluate -Dexpression=who | grep -v "auto-discovered"
Apache Maven 3.10.0 (c43a36b8d67be7e0805a411bc0898af1a51f5472)
Maven home: <scratch>/tools/apache-maven-3.10.0
Java version: 26, vendor: Oracle Corporation, runtime: /Library/Java/JavaVirtualMachines/jdk-26.jdk/Contents/Home
Default locale: es_ES, platform encoding: UTF-8, time zone: Europe/Madrid
OS name: "mac os x", version: "27.0.1", arch: "aarch64", family: "mac"
[INFO] Scanning for projects...
[INFO]
[INFO] Using the MultiThreadedBuilder implementation with a thread count of 2
[INFO]
[INFO] ----------------< org.example.tidepool:tidepool-parent >----------------
[INFO] Building tidepool-parent 1.0.0-SNAPSHOT
[INFO] from pom.xml
[INFO] --------------------------------[ pom ]---------------------------------
[INFO]
[INFO] --- help:3.5.2:evaluate (default-cli) @ tidepool-parent ---
[INFO] No artifact parameter specified, using 'org.example.tidepool:tidepool-parent:pom:1.0.0-SNAPSHOT' as project.
[INFO]
config
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.965 s (Wall Clock)
[INFO] Finished at: 2026-10-16T14:40:07+02:00
[INFO] ------------------------------------------------------------------------
The "thread count of 2" line is the proof that -T, 2 was read as an option and its value. Maven 3.9.16 and 4.0.0-rc-7 printed the
same thread count line. Typical contents of a maven.config are --no-transfer-progress, --fail-at-end, a -T,
and the properties of a CI-friendly build (-Drevision=..., see
CI-Friendly Versions). Keep it free of anything personal: a
profile that only one developer needs is better activated by that developer in the shell.
Who wins: maven.config, MAVEN_ARGS and the command line
The three sources of arguments are applied in a fixed order, and for a property that is set more than once the one applied last wins. A property set in all three places:
ev who
MAVEN_ARGS="-Dwho=args" ev who
MAVEN_ARGS="-Dwho=args" ev who -Dwho=cli
config
args
cli
The order is .mvn/maven.config, then MAVEN_ARGS, then the command line, so the project supplies defaults, the environment
adjusts them, and what is typed has the last word. The output was identical on Maven 3.9.16, 3.10.0 and 4.0.0-rc-7. A
.mavenrc that exports MAVEN_ARGS, as above, takes part as the environment, which is why mavenrc beat config in the previous section.
jvm.config
jvm.config holds JVM options for Maven, one or more per line, and is the project-level counterpart of MAVEN_OPTS. The official
page says it makes MAVEN_OPTS and .mavenrc unnecessary for per-project settings: the file is committed, and everybody gets the
same heap and the same system properties without configuring a shell. This file sets a heap and a property, and asks the JVM
to print its flags:
-Xmx300m
-XX:+PrintFlagsFinal
-Dbase.dir=${MAVEN_PROJECTBASEDIR}
ev base.dir | grep -w "MaxHeapSize\|base.dir\|null.*\|/private.*"
The grep keeps the heap line and the value of base.dir. Results by version:
| Maven | Heap size line | Value of base.dir |
|---|---|---|
3.9.16 |
|
|
3.10.0 |
|
|
4.0.0-rc-7 |
|
|
Expanding MAVEN_PROJECTBASEDIR inside jvm.config is listed in the Maven 3.10.0 release notes. It is useful to point an option
at a file kept in the repository, such as -Djava.util.logging.config.file=... or a truststore.
Two further differences between Maven 3 and Maven 4 showed up in the same experiments. The first is the order in which
jvm.config and MAVEN_OPTS are combined. When two options conflict, the JVM keeps the last one. The launcher script of
Maven 3.9.16 and 3.10.0 builds the options as the contents of jvm.config followed by MAVEN_OPTS (line 214 of the 3.10.0
script); the script of Maven 4.0.0-rc-7 appends the contents of jvm.config after MAVEN_OPTS. With -Xmx300m in the file and
MAVEN_OPTS=-Xmx512m:
Maven 3.9.16 MaxHeapSize = 536870912 (MAVEN_OPTS wins)
Maven 3.10.0 MaxHeapSize = 536870912 (MAVEN_OPTS wins)
Maven 4.0.0-rc-7 MaxHeapSize = 318767104 (jvm.config wins)
In Maven 3 the person running the build can therefore override the project; in Maven 4 the project can force its value. Check this if a build is moved between the two.
The second difference is quoting. Maven 3 splits jvm.config into words with the shell, and a quotation mark is not interpreted.
An option that contains a space and is written with quotes made the JVM fail to start. The file contained one line,
-Dwith.space="a b":
ev with.space
Error: Could not find or load main class b"
Caused by: java.lang.ClassNotFoundException: b"
That is the output of Maven 3.9.16 and 3.10.0. Maven 4.0.0-rc-7, whose distribution contains a Java helper for reading
the file (bin/JvmConfigParser.java), printed a b. A Maven 3 file should avoid values with spaces.
The example in the official page is -Xmx2048m -Xms1024m -XX:MaxPermSize=512m -Djava.awt.headless=true. It is out of date. The
MaxPermSize option was removed together with the permanent generation in Java 8, and a modern JVM refuses to start with it. This is what a
file containing exactly that line did on Maven 3.10.0 with JDK 26:
Unrecognized VM option 'MaxPermSize=512m'
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.
Use only the heap options of that line (and -Djava.awt.headless=true, which is still valid).
Source: Maven 3.10.0 release notes
extensions.xml
A core extension is a library that is loaded into Maven itself, before the build starts, and can replace or add components:
for example the Build Cache extension, a Develocity extension, or a custom lifecycle. It is different from a build extension
declared inside a POM (<build><extensions>), which is only known after the POM has been read. The page
Extensions covers what extensions can do and how they are written; this section is
only about where they are declared.
Until Maven 3.2.5 an extension had to be copied by hand into lib/ext of the installation, which meant changing every
developer’s Maven. The mechanism of .mvn/extensions.xml replaced that. The file lists Maven coordinates, with the same
groupId, artifactId and version as any dependency, and Maven downloads the extension and its transitive dependencies.
The following file loads the Build Cache extension, version 1.3.0:
<?xml version="1.0" encoding="UTF-8"?>
<extensions xmlns="http://maven.apache.org/EXTENSIONS/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/EXTENSIONS/1.1.0 https://maven.apache.org/xsd/core-extensions-1.1.0.xsd">
<extension>
<groupId>org.apache.maven.extensions</groupId>
<artifactId>maven-build-cache-extension</artifactId>
<version>1.3.0</version>
</extension>
</extensions>
Running Maven 3.10.0 in the project, the extension announces itself before Maven starts scanning for projects. The grep
keeps only the extension’s own lines, and the path was shortened:
mvn -N org.apache.maven.plugins:maven-help-plugin:3.5.2:evaluate -Dexpression=who | grep -i "cache"
[INFO] Cache configuration is not available at configured path <project>/.mvn/maven-build-cache-config.xml, cache is enabled with defaults
[INFO] Using XX hash algorithm for cache
(The extension then also reports that caching is disabled for the parent project, because it has packaging pom.) The
cache itself is the subject of
Build Performance: Cache, Parallel Builds & mvnd.
Before Maven 3.10 only the project could declare core extensions this way. The Maven 3.10.0 release notes add "support for
user-wide extensions (in ~/.m2/extensions.xml) and installation-wide extensions (in $MAVEN_HOME/conf/extensions.xml)", in
addition to the project’s. The same extension file was placed in each of the three locations (for the user one, the home directory
was redirected with -Duser.home, see the next section) and the "Using XX hash" line of the extension was counted:
| Location of the file | 3.9.16 | 3.10.0 | 4.0.0-rc-7 |
|---|---|---|---|
|
loaded |
loaded |
loaded |
|
ignored |
loaded |
loaded |
|
ignored |
loaded |
not run here |
For the installation-wide file a copy of each distribution was used, so that the real installation was not modified. The
installation-wide location was not run on Maven 4.0.0-rc-7, but the configuration table in the next section lists
maven.installation.extensions as ${maven.installation.conf}/extensions.xml and maven.user.extensions as
${maven.user.conf}/extensions.xml.
User-wide and installation-wide extensions apply to every build of the machine, including builds of projects that never heard of
them, so they suit tools that observe or accelerate (a build scanner, a mirror selector) rather than ones that change the output. A
project that needs a core extension to build correctly should declare it itself, in .mvn/extensions.xml.
Source: Maven: core-extensions-1.1.0.xsd
Source: Maven 3.10.0 release notes
What Maven 4 adds to .mvn
Maven 4 reads the same three files and gives the directory a more formal definition. The conf/maven-system.properties file of the
4.0.0-rc-7 distribution defines three directories and the files inside them:
maven.installation.conf = ${maven.home}/conf
maven.user.conf = ${user.home}/.m2
maven.project.conf = ${session.rootDirectory}/.mvn
On top of these, the settings, toolchains and extensions files exist at three levels (maven.installation.settings,
maven.user.settings, maven.project.settings, and the same for toolchains and extensions), so .mvn/settings.xml is a
project-level settings file in Maven 4 (not run here). Properties can also be set from files rather than the command line:
conf/maven-user.properties of the distribution includes, when they exist, ${maven.user.conf}/maven-user.properties,
maven.properties in the same directory, and the two names in .mvn. A file .mvn/maven-user.properties with the line
who=userprops made Maven 4.0.0-rc-7 print:
ev who
userprops
and Maven 3.10.0, on the same project, printed null object or invalid expression. The distribution’s own comment says that
maven.properties "will be removed in Maven 4.1.0" and only maven-user.properties will be loaded, so use that name. These
properties are user properties, the same as -D ones.
The local repository
Every artifact that Maven downloads or installs goes to the local repository, which defaults to ~/.m2/repository in Maven
3 (and to ${maven.user.conf}/repository, the same place, in the Maven 4 configuration table). Three mechanisms change it.
settings.xml
The official guide puts <localRepository> in the user’s settings.xml, and adds that the path "must be an absolute path":
<settings>
...
<localRepository>/path/to/local/repo/</localRepository>
...
</settings>
To prove the setting is read, the run redirected the JVM’s notion of the home directory with -Duser.home (set in MAVEN_OPTS)
to the scratch home, whose .m2/settings.xml contains <localRepository> pointing at <lab>/home/shared-repo.
Setting HOME, as for .mavenrc, would not have been enough: Java does not take user.home from that variable on this system.
MAVEN_OPTS="-Duser.home=<lab>/home" ev settings.localRepository
<lab>/home/shared-repo
maven.repo.local
The system property maven.repo.local overrides the setting, and, because it is a property, it can be set in maven.config or
MAVEN_ARGS:
ev settings.localRepository -Dmaven.repo.local=<project>/cli-repo
<project>/cli-repo
The next run put a relative path in .mvn/maven.config, a common way to give a project its own local repository
(-Dmaven.repo.local=.mvn/local-repo). The path is resolved against the directory the command is run from, not against the
directory of .mvn:
ev settings.localRepository
cd app && ev settings.localRepository
<project>/.mvn/local-repo
<project>/app/.mvn/local-repo
That is Maven 3.10.0; 3.9.16 and 4.0.0-rc-7 gave the first line when run from the root. Running inside the module created a second
repository under app. Prefer an absolute path, and
remember that a per-project repository downloads everything again, once for each project.
Chained repositories: maven.repo.local.tail
Since Maven 3.9.0 a read-only "tail" of one or more repositories can be consulted before Maven goes to the network, while writes go
to the main local repository. This is how a CI image can ship a pre-populated cache and still run each job with a clean, disposable
repository. The experiment counted the artifacts downloaded by the same Help plugin run into a new, empty local repository, once
without and once with the existing ~/.m2/repository as the tail (Maven 3.10.0):
mvn -N org.apache.maven.plugins:maven-help-plugin:3.5.2:evaluate -Dexpression=who -Dmaven.repo.local=<lab>/r
mvn -N org.apache.maven.plugins:maven-help-plugin:3.5.2:evaluate -Dexpression=who -Dmaven.repo.local=<lab>/r \
-Dmaven.repo.local.tail=<home>/.m2/repository
70 downloads, 18 JARs, 49 POMs
3 downloads, 0 JARs, 0 POMs
(The two lines were obtained by counting the "Downloaded from" lines of Maven’s output; the three downloads of the second run were
metadata files for the plugin lookup.) The other keys of the family, from the Maven configuration table, are
maven.repo.local.tail.ignoreAvailability (default true), maven.repo.local.head (Maven 4.0.0: prepends instead of appends)
and maven.repo.local.recordReverseTree (3.9.0, false by default), which, when true, records in the local repository why an
artifact is there. That last key was tried here, and no .tracking directory appeared for the Help plugin run; it is a diagnostic
for a build with dependencies, and it is not demonstrated.
Repositories to download from, mirrors and the layout of the local repository are on Repositories, Mirrors & Repository Managers.
Parallel artifact resolution
The configuring guide notes that by default Maven downloads up to five artifacts at once, and that -Dmaven.artifact.threads=1
reduces it, permanently through MAVEN_OPTS (for example export MAVEN_OPTS=-Dmaven.artifact.threads=3). That text was
written for the old resolver; the property name was not checked against Maven 3.10.0’s resolver, and no run was made (not run
here). The reactor’s own parallelism is a different thing and is controlled with -T, which belongs in maven.config.
Shell completion
Neither distribution used for this page (3.10.0 and 4.0.0-rc-7) contains a completion script: a search of both unpacked trees for
files with "complet" in the name found nothing, and the launcher scripts do not mention it. Completion for the mvn command is
therefore something the packager or the user adds. The Apache project does not publish one for the Maven 3 command; a widely
used community script is
maven-bash-completion. It was not installed or run here, so nothing is claimed about
how well it knows Maven 3.10’s options or plugins. Package managers may install a completion file next to Maven (not run here). Maven 4’s
distribution adds the interactive shell mvnsh (not run here).
Source: Community: maven-bash-completion
The configuration keys
Besides plugin parameters, Maven has its own keys, which are plain system or user properties that configure the core and the resolver. The reference is the "Maven Configuration Options" table in the Maven 4 documentation, generated from the code, with a default and the version that introduced each key. "Since" refers to when the key appeared in the documentation; a key marked 4.0.0 might be absent from Maven 3. This selection is from the 4.0.0-rc-7 table:
| Key | Purpose | Default | Since |
|---|---|---|---|
|
The three configuration directories. |
|
4.0.0 |
|
The local repository. |
|
3.0.0 |
|
Read-only chained local repositories (comma-separated). |
none |
3.9.0 |
|
Record why an artifact is in the local repository. |
|
3.9.0 |
|
Format of |
|
3.0.0 |
|
Plugin validation level ( |
|
3.9.2 |
|
Plugins to exclude from validation. |
none |
3.9.6 |
|
|
|
3.10.0 |
|
A semicolon-separated list of filters on version ranges (for example |
none |
3.10.0 |
|
Resolver transport: |
|
4.0.0 |
|
Colour of the output: |
|
4.0.0 |
|
URL of Maven Central; the |
|
4.0.0 |
|
Make Maven 4 behave like Maven 3. |
|
4.0.0 |
The table also has the maven.logger.* keys, maven.consumer.pom.* keys for the consumer POM (see
Maven 4: POM Model & Consumer POM) and
maven.relocations.entries for user-defined relocations. Which of them Maven 3.10.0 honours is documented in its own release notes
and not in this table, so test a key before depending on it.
One entry behaves differently from the others. maven.build.timestamp.format is a model property, read from the POM. A property
build.stamp was defined as ${maven.build.timestamp} and the format was set in the POM’s <properties> to yyyyMMdd-HHmm; the
build printed the same value on Maven 3.9.16, 3.10.0 and 4.0.0-rc-7, and a -Dmaven.build.timestamp.format=yyyy on the command line
had no effect:
20261016-1239
The unmodified output without the property is the default format with a trailing Z, for example 2026-10-16T12:39:04Z.
Choosing where a setting belongs
| You want to… | Put it in… | Why |
|---|---|---|
Give every contributor and CI the same heap |
|
It is versioned with the code. Remember the Maven 3 versus 4 order against |
Run every build in batch mode with two threads |
|
One option per line; a developer can still override with the command line. |
Always add |
|
It does not change the checkout and wins over |
Choose the JDK that runs Maven |
|
See Installation; use toolchains for the JDK that compiles (Compiling & Toolchains). |
Load a build scanner on every build of a machine |
|
Not needed in the repository; ignored by 3.9.16. |
Pin a Maven version for a project |
The wrapper in |
See Maven Wrapper. |
Move the local repository |
|
Absolute paths only. |
Share company-wide project information |
A parent POM, not Maven’s configuration |
The guide says installation and user configuration "cannot be used to add shared project information". |
Problems and their usual causes are collected in
Troubleshooting & Best Practices. Moving to the
release candidate changes some of the above (the jvm.config order, quoting, new .mvn files); see
Migrating to Maven 4.