Why Maven 4’s New POM Model and Flattening Features Matter for Modern Java Projects

Maven 4 introduces a revamped POM model, native flattening, explicit artifact types, subproject support, a tree‑based lifecycle and richer configuration options, enabling faster, cleaner, and more predictable builds for Java projects that have evolved dramatically over the past fifteen years.

Su San Talks Tech
Su San Talks Tech
Su San Talks Tech
Why Maven 4’s New POM Model and Flattening Features Matter for Modern Java Projects

POM Model Upgrade: From 4.0.0 to 4.1.0

Maven 4 upgrades the POM model version to 4.1.0 , allowing backward compatibility while unlocking new capabilities. The new model can be declared as follows:

<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 http://maven.apache.org/xsd/maven-4.1.0.xsd">
  <modelVersion>4.1.0</modelVersion>
</project>

Key points:

Backward compatible : Maven 4 can still build POMs that use version 4.0.0.

New features only apply when the model version is 4.1.0.

The modelVersion element can be omitted; Maven will infer it from the schema.

Even without upgrading the POM, you can run Maven 4, but upgrading lets you reap the full benefits.

Build POM / Consumer POM Separation: Solving "POM Pollution"

Maven 4 introduces a fundamental change by separating the build‑time POM from the consumer‑facing POM.

In Maven 3, a published POM contains plugin configuration, build details, parent references, and many unused properties, forcing downstream users to parse irrelevant information.

Maven 4’s solution is POM flattening , producing two distinct POM types:

Build POM : Used for the project’s own build.

Consumer POM : Delivered to dependents and contains only the essential transitive dependencies, resolved properties, and no plugin or parent information.

Features of the Consumer POM:

No plugin configuration.

No parent POM.

No unused dependencies.

Retains only real transitive dependencies.

All properties are resolved to concrete values.

Enable flattening with:

mvn clean install -Dmaven.consumer.pom.flatten=true
In Maven 3 you needed the external Flatten Maven Plugin; Maven 4 provides this as a native capability.

New Artifact Types: Explicit Control of Classpath / Module Path

Maven 3 implicitly decided whether a JAR belonged on the classpath or module path based on the presence of module-info.class. Maven 4 adds explicit types:

<type>classpath-jar</type>
<type>module-jar</type>

This lets developers declare exactly where a dependency should be placed.

Maven 4 also introduces dedicated processor types, e.g., processor, classpath-processor, and modular-processor. An example with Lombok:

<dependencies>
  <dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>${lombok.version}</version>
    <type>classpath-processor</type>
  </dependency>
  <dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>${lombok.version}</version>
    <scope>provided</scope>
  </dependency>
</dependencies>

Maven 4 clearly separates the API classpath from the processor classpath, improving build semantics and tool‑chain optimization.

Modules Renamed to Subprojects: Paving the Way for Java 9

With Java 9’s module system, Maven’s traditional modules element caused confusion. Maven 4 deprecates modules and replaces it with subprojects:

<subprojects>
  <subproject>project-a</subproject>
  <subproject>project-b</subproject>
</subprojects>

Additional improvements:

Parent inference: an empty <parent /> is auto‑detected.

Automatic subproject discovery without explicit declaration.

Unified build timestamps.

Safe release: if any subproject fails, the whole multi‑module build is aborted.

Tree‑Based Lifecycle: Parallel Builds Made Legitimate

Maven 3’s lifecycle is linear, making parallel builds difficult for large multi‑module projects. Maven 4 introduces a Tree‑based Lifecycle where each subproject progresses independently as soon as its dependencies are ready, dramatically speeding up large builds.

mvn -b concurrent verify

Configuration Enhancements: Small Changes, Big Impact

1. Conditional Profile Expressions

Profiles can now use full expression syntax instead of simple OS or JDK checks:

<condition>
  exists('${project.basedir}/src/**/*.xsd') && length(${user.name}) > 5
</condition>

2. Unified sources Model

Maven 3 required separate sourceDirectory and testSourceDirectory elements. Maven 4 consolidates them under a sources element, supporting multiple directories, versions, and modular projects without extra plugin configuration:

<sources>
  <source>
    <scope>main</scope>
    <directory>my-custom-dir/foo</directory>
  </source>
  <source>
    <scope>test</scope>
    <directory>my-custom-dir/bar</directory>
  </source>
</sources>

Official Upgrade Tool

Maven 4 ships with mvnup, which analyses the existing POM, plugins, and project structure, then generates executable upgrade suggestions.

mvnup check   # only generate a report
mvnup apply   # automatically apply the changes

This tool helps teams transition to Maven 4 with confidence.

JavaBuild Tooldependency managementmavenPOMMaven4
Su San Talks Tech
Written by

Su San Talks Tech

Su San, former staff at several leading tech companies, is a top creator on Juejin and a premium creator on CSDN, and runs the free coding practice site www.susan.net.cn.

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.