如果子节点的pom版本与父节点的聚合器pom及其子模块不同,则避免使用错误的版本插值

时间:2016-08-11 06:41:07

标签: maven pom.xml versioning parent-pom

问题描述

我们有一个Maven聚合器pom,其中一些子poms(模块)都具有相同的版本:

pom.xml (parent zoo, version 2.0.0)
|-- pom.xml (child module cat, version 2.0.0)
|-- pom.xml (child module dog, version 2.0.0)
|-- ...

在依赖关系管理部分中,所有子项都使用项目版本声明,以简化依赖关系的声明。 父pom看起来像

<groupId>com.acme</groupId>
<artifactId>zoo</artifactId>
<version>2.0.0</version>
<packaging>pom</packaging>

<modules>
  <module>cat</module>
  <module>dog</module>
</modules>

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>com.acme</groupId>
      <artifactId>cat</artifactId>
      <version>${project.version}</version>
    </dependency>
    <!-- other child modules go here -->
  </dependencies>
</dependencyManagement>

儿童poms被定义为

<parent>
  <groupId>com.acme</groupId>
  <artifactId>zoo</artifactId>
  <version>2.0.0</version>
</parent>

<groupId>com.acme</groupId>
<artifactId>cat</artifactId>

<dependencies>
  <dependency>
    <groupId>com.acme</groupId>
    <artifactId>dog</artifactId>
  </dependency>
</dependencies>

还有另一个pom声明父pom也是其父(继承),但未在此父级中列为子模块(无聚合)。这个pom有不同的版本。

<parent>
  <groupId>com.acme</groupId>
  <artifactId>zoo</artifactId>
  <version>2.0.0</version>
</parent>

<groupId>com.acme</groupId>
<artifactId>boo</artifactId>
<version>1.0.0</version>

<dependencies>
  <dependency>
    <groupId>com.acme</groupId>
    <artifactId>dog</artifactId>
  </dependency>
</dependencies>

实际上我们已经预期依赖项com.acme.dog的版本是从父pom com.acme.zoo的依赖关系管理部分提取的,并且等于2.0.0。但是Maven documentation on project interpolation and variables

  

需要注意的一个因素是,如上所述,这些变量在继承之后进行处理。这意味着如果父项目使用变量,那么它在子项中的定义(而不是父项)将是最终使用的项。

即:在反应堆构建中,父pom ${project.version}的依赖关系管理部分中使用的变量com.acme.zoo将根据com.acme.bar进行评估,并等于1.0.0什么不是预期的。

注意

在父pom中使用变量需要与父pom版本保持同步。但是,此解决方案与Maven Release Plugin不兼容。

问题

我们如何实现理想的行为

  • 具有相同版本的儿童的聚合器pom
  • 依赖关系管理部分中的子项声明,以确保所有依赖项具有相同的版本
  • 将继承与不同版本一起使用
  • maven-release-plugin的兼容性

没有项目插值变量的缺陷吗?

3 个答案:

答案 0 :(得分:4)

maven发布插件能够更改父pom中管理的依赖项的版本。

因此,如果你像这样定义你的maven父母:

<groupId>com.acme</groupId>
<artifactId>zoo</artifactId>
<version>2.0.0-SNAPSHOT</version>
<packaging>pom</packaging>

<modules>
  <module>cat</module>
  <module>dog</module>
</modules>

<dependencyManagement>
 <dependencies>
   <dependency>
     <groupId>com.acme</groupId>
     <artifactId>cat</artifactId>
     <version>2.0.0-SNAPSHOT</version>
   </dependency>
   <!-- other child modules go here -->
 </dependencies>
</dependencyManagement>

如您所见,父版本和托管依赖项的版本相同。我将它们设置为SNAPSHOT版本,因为发布插件将在发布时创建最终版本:执行

你的孩子可以像你一样留下来。

因为在您的设置中,您的父项目也是反应堆,然后您可以调用

mvn release:perform -DautoVersionSubmodules=true

将在运行此命令时更新所有子模块中父项的版本。该选项与运行

时基本相同
mvn versions:update-child-modules

意思是它将改变孩子的poms。

运行mvn release:perform命令后,您的父pom将如下所示:

<groupId>com.acme</groupId>
<artifactId>zoo</artifactId>
<version>2.0.1-SNAPSHOT</version>
<packaging>pom</packaging>

<modules>
  <module>cat</module>
  <module>dog</module>
</modules>

<dependencyManagement>
 <dependencies>
   <dependency>
     <groupId>com.acme</groupId>
     <artifactId>cat</artifactId>
     <version>2.0.1-SNAPSHOT</version>
  </dependency>
  <!-- other child modules go here -->
 </dependencies>
</dependencyManagement>

你的孩子喜欢这样

<parent>
  <groupId>com.acme</groupId>
  <artifactId>zoo</artifactId>
  <version>2.0.1-SNAPSHOT</version>
</parent>

<groupId>com.acme</groupId>
<artifactId>cat</artifactId>

<dependencies>
  <dependency>
    <groupId>com.acme</groupId>
    <artifactId>dog</artifactId>
  </dependency>
</dependencies>

最终版本只存在于release:prepare命令创建的标记中。

PS:在运行release:prepare命令后提示时,您可以为最终版本和下一个开发版本定义其他版本。

答案 1 :(得分:2)

最简单的解决方案是修改动物园的pom并将<version>${project.version}</version>替换为<version>2.0.0</version>

请注意:

  1. 将版本更改为下一个数字时,例如2.0.1,用 versions-maven-plugin,依赖管理部分也将如此 更新

  2. Spring使用最简单的解决方案,请参阅 http://central.maven.org/maven2/org/springframework/spring-framework-bom/4.2.7.RELEASE/spring-framework-bom-4.2.7.RELEASE.pom

  3. 总结:在依赖关系管理中使用<version>${project.version}</version>是错误的想法。

答案 2 :(得分:0)

来自Maven pom简介:http://maven.apache.org/guides/introduction/introduction-to-the-pom.html

项目继承&gt;实施例1&gt;解决方案

  

或者,如果我们想要groupId和/或你的版本   模块与其父模块相同,可以删除groupId   和/或模块在其POM中的版本标识。

<project>
  <parent>
    <groupId>com.mycompany.app</groupId>
    <artifactId>my-app</artifactId>
    <version>1</version>
  </parent>
  <modelVersion>4.0.0</modelVersion>
  <artifactId>my-module</artifactId>
</project>