What Maven 4 Brings: POM Model Upgrade, Flattened Consumer POM, and Parallel Builds
Maven 4 introduces a new POM model version 4.1.0, separates build and consumer POMs to eliminate POM pollution, adds explicit artifact types for classpath and module paths, renames modules to subprojects, and implements a tree‑based lifecycle for true parallel builds, all while offering enhanced configuration capabilities.
POM Model Upgrade: 4.0.0 → 4.1.0
Maven 4 introduces a new POM model version 4.1.0 . The minimal POM looks like:
<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>Backward compatible : Maven 4 can still build POMs that declare modelVersion 4.0.0.
All new Maven 4 capabilities are only activated when the POM uses version 4.1.0.
The modelVersion element may be omitted; Maven derives it from the XML schema.
Even without upgrading the POM you can run Maven 4, but only the upgraded POM unlocks the new features.
Build POM / Consumer POM Separation (POM Flattening)
In Maven 3 the published POM contains build‑time details (plugin configuration, parent references, unused dependencies, raw properties). Consumers must parse a lot of irrelevant information. Maven 4 adds native POM flattening to produce a clean Consumer POM that is shipped to dependents.
Build POM : used only for the project’s own build.
Consumer POM : published to repositories; contains only real transitive dependencies, resolved property values, and no plugin configuration, parent POM, or unused dependencies.
Enable flattening with the system property:
mvn clean install -Dmaven.consumer.pom.flatten=trueMaven 3 required the external Flatten Maven Plugin; Maven 4 provides this capability out‑of‑the‑box.
Explicit Artifact Types for Classpath / Module‑Path Control
Maven 3 inferred the classpath/module‑path based on the presence of module-info.class. Maven 4 adds explicit types so developers can state the intended location:
<type>classpath-jar</type>
<type>module-jar</type>Annotation‑processor specific types are also introduced:
processor classpath-processor modular-processorExample (Lombok) showing a processor that lives on the classpath and the actual Lombok library used at compile time:
<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>This separation makes the build classpath semantics clearer and enables tooling optimisations.
Modules Renamed to Subprojects (Java 9 Alignment)
The ambiguous modules element is deprecated in favour of subprojects. The new element can be omitted entirely because Maven 4 can infer parent relationships and discover subprojects automatically.
<subprojects>
<subproject>project-a</subproject>
<subproject>project-b</subproject>
</subprojects>Empty <parent /> is auto‑detected.
Subprojects are discovered without explicit declaration.
Build timestamps are unified across the reactor.
If any subproject fails, the whole release is aborted (safe release).
Tree‑Based Lifecycle for Parallel Builds
Maven 3’s lifecycle is linear, making parallel execution of multi‑module builds inefficient. Maven 4 introduces a Tree‑based Lifecycle where each subproject progresses independently as soon as its dependencies are satisfied. mvn -b concurrent verify This dramatically speeds up large reactors.
Configuration Enhancements
1. Conditional Profile Expressions
<condition>exists('${project.basedir}/src/**/*.xsd') && length(${user.name}) > 5</condition>Beyond simple OS or JDK checks, Maven 4 supports full expression evaluation for activating profiles.
2. Unified sources Model
Maven 3 used separate sourceDirectory and testSourceDirectory. Maven 4 consolidates them under a single sources element with scoped entries, allowing multiple source directories, version‑specific sources, and module‑aware configurations without extra plugins.
<sources>
<source>
<scope>main</scope>
<directory>my-custom-dir/foo</directory>
</source>
<source>
<scope>test</scope>
<directory>my-custom-dir/bar</directory>
</source>
</sources>Supports multiple directories per scope.
Works with multi‑version and modular projects.
Eliminates the need for separate plugin configuration for source handling.
Official Upgrade Tool ( mvnup )
Maven 4 ships with mvnup, which analyses POMs, plugins, and project structure and generates executable upgrade suggestions.
mvnup check # generate a report only
mvnup apply # apply automatic changesmacrozheng
Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.
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.
