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:

  1. CLI Option ParsingUpgradeOptions processes arguments. If --all is present, ModelUpgradeStrategy.determineTargetModelVersion forces the target to 4.1.0; otherwise, it uses the value supplied via --model.

  2. POM DiscoveryPomDiscovery recursively walks the project tree, returning a Map<Path, Document> containing every pom.xml file.

  3. Applicability CheckModelUpgradeStrategy.isApplicable returns true when --all was supplied or when the target version differs from the current MODEL_VERSION_4_0_0.

  4. Version Detection – For each POM, ModelVersionUtils.detectModelVersion identifies the current model version, falling back to the XML namespace URI if the <modelVersion> element is absent.

  5. Feasibility ValidationModelVersionUtils.canUpgrade ensures the transition is supported, such as 4.0.0 → 4.1.0.

  6. Core Upgrade ExecutionModelUpgradeStrategy.performModelUpgrade performs three main transformations:

    • Updates or creates the <modelVersion> element via DomUtils.insertContentElement
    • Replaces the root element's xmlns attribute and updates xsi:schemaLocation using ModelVersionUtils.getSchemaLocationForModelVersion
    • Renames <modules> to <subprojects> and <module> to <subproject> for target versions ≥ 4.1.0, including within <profiles> sections
  7. 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 by createPhaseUpgradeMap.

  8. Result Reporting – An UpgradeResult object 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:

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 mvnup command automates Maven 4 POM migrations through the ModelUpgradeStrategy class at priority 40.
  • Model version updates change POMs from 4.0.0 to 4.1.0, including namespace and schema location updates.
  • Structural transformations rename <modules> to <subprojects> and update deprecated phase names to Maven 4 syntax (pre-cleanbefore:clean).
  • Formatting preservation is handled by DomUtils to maintain XML indentation and comments.
  • Validation occurs via ModelVersionUtils.canUpgrade to 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →