Maven 4 Arrives After 15 Years: A Complete Rewrite of the Java Build Tool

Maven 4 (currently at 4.0.0‑rc‑5) introduces a Java 17 runtime requirement, separates Build POM from Consumer POM, adds a new POM 4.1.0 model that reduces repetitive configuration, and provides migration tools such as mvnup and mvnsh, while offering step‑by‑step guidance for upgrading from Maven 3.

java1234
java1234
java1234
Maven 4 Arrives After 15 Years: A Complete Rewrite of the Java Build Tool

Why Maven 4 took so long

Maven 2 (2004) and Maven 3 (2010) left the POM format frozen because the POM had to describe both build configuration and downstream dependency information. Changing the format would require coordinated updates to Maven Central, IDEs, Gradle, and many plugins, so improvements such as automatic parent version inference were postponed for over a decade.

Current status (July 2026)

The latest release candidate is 4.0.0‑rc‑5 (2025‑11‑13). It is marked for testing; production use is recommended after the GA release. Maven 4 itself requires Java 17+, but projects can still compile with older JDKs via toolchains.

Running Maven itself: Java 8+ (Maven 3) → Java 17+ (Maven 4)

Compiling project code: self‑configured (Maven 3) → still can compile Java 8/11/17 etc. (Maven 4)

POM model: 4.0.0 (Maven 3) → build‑usable 4.1.0 (Maven 4)

Dependency resolution: Resolver 1.x (Maven 3) → Resolver 2.0 (Maven 4)

Core change: Build POM vs Consumer POM

Build POM : stored in the Git repository, contains full plugin configuration, properties, parent references, etc.

Consumer POM : the trimmed POM published to Maven Central, keeping only the dependency information required by downstream consumers.

After a successful build, Maven 4 automatically generates the Consumer POM by inlining parent content, removing plugin configuration, and discarding unused dependencies.

Enabling Consumer POM publishing

In rc‑5 the flattening of the Consumer POM is disabled by default. Enable it by adding the property:

<!-- .mvn/maven-user.properties -->
maven.consumer.pom.flatten=true

or on the command line:

mvn deploy -Dmaven.consumer.pom.flatten=true

POM 4.1.0: Reduce repetitive configuration

1. Automatic parent POM version inference

Sub‑modules no longer need an explicit <version> element; Maven infers it from the parent directory.

<project xmlns="http://maven.apache.org/POM/4.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.1.0 https://maven.apache.org/xsd/maven-4.1.0.xsd">
  <!-- version omitted, Maven infers it from the parent directory -->
  <parent>
    <groupId>com.example</groupId>
    <artifactId>my-app-parent</artifactId>
  </parent>
  <artifactId>my-service</artifactId>
  <dependencies>
    <!-- same‑repo submodule dependencies can also omit version -->
    <dependency>
      <groupId>com.example</groupId>
      <artifactId>my-common</artifactId>
    </dependency>
  </dependencies>
</project>

2. Automatic submodule discovery

If a project uses pom packaging and does not declare a <subprojects> element, Maven 4 scans sub‑directories for pom.xml files and adds them automatically.

<project xmlns="http://maven.apache.org/POM/4.1.0">
  <modelVersion>4.1.0</modelVersion>
  <groupId>com.example</groupId>
  <artifactId>my-app-parent</artifactId>
  <version>1.0.0‑SNAPSHOT</version>
  <packaging>pom</packaging>
  <!-- No <subprojects>; any subdirectory containing pom.xml is added to the build -->
</project>

3. CI‑friendly versioning without the flatten‑maven‑plugin

Maven 4 supports the ${revision} placeholder natively.

<groupId>com.example</groupId>
<artifactId>my-app</artifactId>
<version>${revision}</version>

Specify the revision in a CI pipeline: mvn verify -Drevision=1.2.0 Or fix it in .mvn/maven.config:

-Drevision=1.0.0‑SNAPSHOT

4. New BOM packaging type

A dedicated bom packaging separates Bill‑of‑Materials responsibilities from parent POMs.

<project xmlns="http://maven.apache.org/POM/4.1.0">
  <modelVersion>4.1.0</modelVersion>
  <groupId>com.example</groupId>
  <artifactId>my-app-bom</artifactId>
  <version>1.0.0</version>
  <packaging>bom</packaging>
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-dependencies</artifactId>
        <version>3.4.0</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
</project>

5. Multiple source directories without the build‑helper plugin

Define several source directories directly in the <build> section.

<build>
  <sources>
    <source>
      <scope>main</scope>
      <directory>src/main/java</directory>
    </source>
    <source>
      <scope>main</scope>
      <directory>src/main/kotlin</directory>
    </source>
    <source>
      <scope>test</scope>
      <directory>src/test/java</directory>
    </source>
  </sources>
</build>

New tools and daily‑experience upgrades

Maven Upgrade Tool ( mvnup )

Checks project compatibility with Maven 4 and applies recommended POM fixes.

# Check compatibility
mvnup check

# Apply automatic fixes
mvnup apply

Maven Shell ( mvnsh )

Interactive REPL‑like shell for Maven commands.

mvnsh
# Inside the shell
mvn> compile
mvn> test -pl my-service
mvn> exit

Resume after build failure

The -r / --resume flag continues from the failed module and skips modules that have already succeeded.

# Full build
mvn verify

# After fixing code, resume from failure
mvn verify -r

Migration decision process

How to migrate from Maven 3

Try locally first : install Maven 4 RC with JDK 17 and run mvnup check.

Upgrade plugins : update enforcer, shade, remote‑resources, etc., to their latest versions.

Pin plugin versions : Maven 4’s Super POM changes default plugin versions; declare explicit versions to avoid unexpected behavior.

Parallel CI validation : keep the Maven 3 pipeline and add a Maven 4 trial pipeline.

Switch after GA : use RC for experimentation; wait for the GA release for production.

Minimal verification example:

# Download and extract Maven 4
curl -L -O https://archive.apache.org/dist/maven/maven-4/4.0.0-rc-5/binaries/apache-maven-4.0.0-rc-5-bin.tar.gz
tar -xzf apache-maven-4.0.0-rc-5-bin.tar.gz

# Run Maven 4 without affecting the system Maven
/path/to/apache-maven-4.0.0-rc-5/bin/mvn -version

# Check project compatibility
/path/to/apache-maven-4.0.0-rc-5/bin/mvnup check
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaMigrationautomationBuild ToolMavenciPOMMaven 4
java1234
Written by

java1234

Former senior programmer at a Fortune Global 500 company, dedicated to sharing Java expertise. Visit Feng's site: Java Knowledge Sharing, www.java1234.com

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.