本文最后更新于 2025-06-14,文章内容可能已经过时。

pom.xml 中使用了 ${revision} 占位符,但没有使用 flatten-maven-plugin 插件。这是一个常见的做法,特别是在多模块 Maven 项目中用于统一管理版本号。下面详细分析一下:如果不使用 flatten-maven-plugin,会带来哪些潜在问题或限制?

一、背景知识:什么是 ${revision}flatten-maven-plugin

1. ${revision} 是什么?

Maven 3.5+ 支持使用 ${revision}${groupId}${artifactId} 等变量作为占位符,在 <parent> 或子模块中统一定义版本信息。

例如:

<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>my-project</artifactId>
    <version>${revision}</version>
    ...
</project>

这样可以在父 POM 中统一定义 <revision>1.0.0</revision>,所有子模块都可以继承这个版本。

2. flatten-maven-plugin 是什么?

它是一个插件,作用是生成一个“扁平化”的 pom.xml(通常为 pom.xml.flat),将所有变量(如 ${revision})替换为实际值,并去除开发时使用的配置(如 <modules><dependencyManagement> 等)。

主要用于:

  • 发布到 Maven 仓库的 pom.xml 应该是静态的、不含变量的。
  • 避免下游用户解析失败(因为他们的 Maven 可能无法识别 ${revision})。

二、不使用 flatten-maven-plugin 的问题

如果你只用了 ${revision},但没有使用 flatten-maven-plugin 插件进行发布前处理,可能会遇到以下问题:

1. 发布到仓库后,pom.xml 中包含 ${revision}

下游用户使用你的依赖时,如果他们用的是旧版本的 Maven(<3.5),或者某些 CI 工具、IDE 不支持 ${revision},就会导致构建失败。

Failed to read artifact descriptor for com.example:my-module:jar:${revision}

2. 依赖解析失败

一些工具(比如 Nexus、Jenkins、CI/CD 流水线、Gradle 构建)可能无法正确解析带有 ${revision} 的 POM 文件,从而导致依赖下载失败。

3. 不符合 Maven Central 等公共仓库的要求

如果你计划发布到 Maven Central 或其他公共仓库,这些仓库要求你的 pom.xml 是静态的、可读的、不包含变量。否则会被拒绝上传。

4. 小结:是否必须使用 flatten-maven-plugin

场景是否需要 flatten-maven-plugin
本地开发 / 多模块项目内部使用❌ 不强制
使用 ${revision} 并要发布到私有仓库⚠️ 建议使用
发布到 Maven Central / 公共仓库✅ 必须使用
下游用户使用低版本 Maven✅ 推荐使用

✅ 推荐解决方案

如果你打算发布项目到远程仓库(无论是私有还是公共),请务必添加 flatten-maven-plugin,并在构建时执行 flatten 操作。

示例配置(推荐):

<!-- 统一 revision 版本 -->
<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>flatten-maven-plugin</artifactId>
    <version>1.6.0</version>
    <configuration>
        <flattenMode>oss</flattenMode>
        <updatePomFile>true</updatePomFile>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>flatten</goal>
            </goals>
            <id>flatten</id>
            <phase>process-resources</phase>
        </execution>
        <execution>
            <goals>
                <goal>clean</goal>
            </goals>
            <id>flatten.clean</id>
            <phase>clean</phase>
        </execution>
    </executions>
</plugin>

插件会在打包和部署前自动将 pom.xml 扁平化,确保发布的版本是静态的、不含变量。