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.
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=trueIn 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 verifyConfiguration 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 changesThis tool helps teams transition to Maven 4 with confidence.
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.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
