How Maven’s mvnup Model Upgrade Migration Works for POM Files
The mvnup command automates Maven POM migrations from model version 4.0.0 to 4.1.0 by executing the ModelUpgradeStrategy, which updates XML namespaces, converts deprecated <modules> elements to <subprojects>, migrates legacy phase names to Maven 4 syntax, and preserves original formatting.
Maven 4 introduces a stricter POM model with version 4.1.0 and a revised XML namespace. To help developers transition existing projects, the apache/maven repository provides the mvnup command-line tool, which implements a Maven mvnup model upgrade migration strategy that handles structural transformations automatically.
Architecture of the mvnup Migration Tool
The migration tool follows a strategy-based architecture where specialized components handle distinct aspects of the upgrade process.
Entry Points and Orchestration
The migration begins in impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/goals/Help.java, which parses CLI options such as --model and --all. The StrategyOrchestrator class, located at impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/goals/StrategyOrchestrator.java, coordinates execution by discovering POM files and invoking applicable strategies in priority order. The Model‑Upgrade strategy runs at approximately priority 40.
Context and Utility Classes
The UpgradeContext class (impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/UpgradeContext.java) maintains the InvokerRequest, parsed UpgradeOptions, and provides indented logging helpers for progress reporting. ModelVersionUtils (impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/goals/ModelVersionUtils.java) detects current model versions by inspecting the <modelVersion> element or falling back to the XML namespace URI, and validates upgrade feasibility via canUpgrade(current, target). Low-level XML manipulation that preserves formatting and indentation is handled by DomUtils (impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/goals/DomUtils.java).
Step-by-Step Migration Flow
The ModelUpgradeStrategy implements the core migration logic through the following sequence:
-
CLI Option Parsing –
UpgradeOptionsprocesses arguments. If--allis present,ModelUpgradeStrategy.determineTargetModelVersionforces the target to4.1.0; otherwise, it uses the value supplied via--model. -
POM Discovery –
PomDiscoveryrecursively walks the project tree, returning aMap<Path, Document>containing everypom.xmlfile. -
Applicability Check –
ModelUpgradeStrategy.isApplicablereturnstruewhen--allwas supplied or when the target version differs from the currentMODEL_VERSION_4_0_0. -
Version Detection – For each POM,
ModelVersionUtils.detectModelVersionidentifies the current model version, falling back to the XML namespace URI if the<modelVersion>element is absent. -
Feasibility Validation –
ModelVersionUtils.canUpgradeensures the transition is supported, such as4.0.0 → 4.1.0. -
Core Upgrade Execution –
ModelUpgradeStrategy.performModelUpgradeperforms three main transformations:- Updates or creates the
<modelVersion>element viaDomUtils.insertContentElement - Replaces the root element's
xmlnsattribute and updatesxsi:schemaLocationusingModelVersionUtils.getSchemaLocationForModelVersion - Renames
<modules>to<subprojects>and<module>to<subproject>for target versions ≥ 4.1.0, including within<profiles>sections
- Updates or creates the
-
Phase Name Migration – Inside
<build>and within profiles, deprecated Maven 3 phase names (e.g.,pre-clean,post-site) are converted to Maven 4 equivalents (before:clean,after:site) using a mapping generated bycreatePhaseUpgradeMap. -
Result Reporting – An
UpgradeResultobject tracks processed, modified, and error POMs for the final console summary.
Key Source Files and Implementation Details
The migration logic is implemented in the following files within the impl/maven-cli module:
-
ModelUpgradeStrategy.java–impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/goals/ModelUpgradeStrategy.javacontains applicability logic (lines 88-110), core upgrade implementation (lines 144-166), and module-to-subproject conversion (lines 198-226). -
ModelVersionUtils.java–impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/goals/ModelVersionUtils.javahandles version detection, upgrade path validation, and supplies namespace and schema location constants. -
StrategyOrchestrator.java–impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/goals/StrategyOrchestrator.javacoordinates discovery and strategy execution. -
PomDiscovery.java–impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/goals/PomDiscovery.javalocates allpom.xmlfiles in multi-module builds. -
DomUtils.java–impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/goals/DomUtils.javapreserves XML formatting during element insertion and removal.
Practical Usage Examples
Running the Migration
# Preview changes without modifying files
mvnup check
# Apply 4.1.0 upgrade to all POMs in the project tree
mvnup apply --all
Transformation Results
Before migration:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<modules>
<module>module-a</module>
<module>module-b</module>
</modules>
<build>
<plugins>
<plugin>
<executions>
<execution>
<phase>pre-clean</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
After mvnup apply --all:
<project xmlns="http://maven.apache.org/POM/4.1.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.1.0
https://maven.apache.org/xsd/maven-4.1.0.xsd">
<modelVersion>4.1.0</modelVersion>
<subprojects>
<subproject>module-a</subproject>
<subproject>module-b</subproject>
</subprojects>
<build>
<plugins>
<plugin>
<executions>
<execution>
<phase>before:clean</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Summary
- The
mvnupcommand automates Maven 4 POM migrations through theModelUpgradeStrategyclass at priority 40. - Model version updates change POMs from
4.0.0to4.1.0, including namespace and schema location updates. - Structural transformations rename
<modules>to<subprojects>and update deprecated phase names to Maven 4 syntax (pre-clean→before:clean). - Formatting preservation is handled by
DomUtilsto maintain XML indentation and comments. - Validation occurs via
ModelVersionUtils.canUpgradeto ensure only supported migration paths are executed.
Frequently Asked Questions
What is the mvnup command in Maven 4?
The mvnup command is a CLI tool introduced in Maven 4 that automates the migration of POM files from the legacy 4.0.0 model to the newer 4.1.0 model. According to the apache/maven source code, it executes strategies like ModelUpgradeStrategy to handle namespace updates, structural changes, and phase name migrations automatically.
How does mvnup determine if a POM needs upgrading?
The ModelUpgradeStrategy.isApplicable method checks if the --all flag was passed or if the target model version differs from the current version. ModelVersionUtils.detectModelVersion identifies the current schema by first inspecting the <modelVersion> element, then falling back to parsing the XML namespace URI if the element is missing.
What structural changes does the Maven model upgrade perform?
Besides updating the model version and XML namespace, the migration renames the <modules> element to <subprojects> and each <module> child to <subproject>, including occurrences within <profiles> sections. It also converts deprecated Maven 3 phase names like pre-clean and post-site to Maven 4's before:clean and after:site syntax using the createPhaseUpgradeMap method.
Are there any prerequisites before running mvnup apply?
Ensure your project is under version control and you have Maven 4 installed. The mvnup check command allows you to preview changes before applying them, as the tool modifies XML files in-place while preserving formatting via DomUtils. The tool validates upgrade paths through ModelVersionUtils.canUpgrade to prevent invalid transitions.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →