Maven项目版本继承——我必须指定父版本吗?

我有两个项目:父项目:A,子项目:B

一个/ pom.xml:

<groupId>com.dummy.bla</groupId>
<artifactId>parent</artifactId>
<version>0.1-SNAPSHOT</version>
<packaging>pom</packaging>

在B/pom.xml中,我有:

    <parent>
<groupId>com.dummy.bla</groupId>
<artifactId>parent</artifactId>
<version>0.1-SNAPSHOT</version>
</parent>


<groupId>com.dummy.bla.sub</groupId>
<artifactId>kid</artifactId>

我想让B继承父的版本,所以在我的例子中,我唯一需要放置0.1-SNAPSHOT的地方是A/pom.xml。但是如果我从父部分下的B/pom.xml中删除<version>0.1-SNAPSHOT</version>, maven会抱怨父部分缺少版本。

是否有一种方法可以使用${project.version}或类似的东西来避免在两个poms中都有01.-SNAPSHOT ?

249983 次浏览

自Maven 3.5.0以来,有一个很好的解决方案,使用${revision}占位符。详见FrVaBe的回答。关于以前的Maven版本,请参阅下面我的原始答案。


不,没有。您总是必须指定父版本。幸运的是,它被继承为模块的版本,这在大多数情况下是可取的。此外,这个父版本声明会被Maven Release Plugin自动替换,所以——事实上——只要你使用Maven Release Plugin来发布或替换版本,你在两个地方有版本并不是问题。

请注意,在某些情况下,这种行为实际上是可以接受的,并且可以为您提供所需的更多灵活性。有时你想要使用以前的父版本来继承,但这不是主流情况。

Maven不是这样设计的,但是有一个解决方案可以实现这个目标(可能有副作用,您必须尝试一下)。诀窍是告诉子项目通过它的相对路径而不是它的纯maven坐标来找到它的父项目,并且在属性中外部化版本号:

父母pom

<groupId>com.dummy.bla</groupId>
<artifactId>parent</artifactId>
<version>${global.version}</version>
<packaging>pom</packaging>


<properties>
<!-- Unique entry point for version number management -->
<global.version>0.1-SNAPSHOT</global.version>
</properties>

孩子pom

<parent>
<groupId>com.dummy.bla</groupId>
<artifactId>parent</artifactId>
<version>${global.version}</version>
<relativePath>..</relativePath>
</parent>


<groupId>com.dummy.bla.sub</groupId>
<artifactId>kid</artifactId>

我曾在我的一个项目中使用过这个技巧,没有遇到任何具体问题,只是maven在构建之初记录了很多警告,这不是很好。

编辑

maven 3.0.4似乎不再允许这样的配置了。

你还可以用:

$ mvn release:update-versions -DdevelopmentVersion={version}

更新pom内的版本号。

IMO更新版本的最简单方法:

$ mvn versions:set -DgenerateBackupPoms=false

(在你的根/父pom文件夹中进行)。

您的POMs将被解析,并询问您要设置哪个版本。

正如Yanflea提到的,有一种方法可以解决这个问题。

在Maven 3.5.0中,您可以使用以下方式从父项目转移版本:

父母POM.xml

<project ...>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mydomain</groupId>
<artifactId>myprojectparent</artifactId>
<packaging>pom</packaging>
<version>${myversion}</version>
<name>MyProjectParent</name>


<properties>
<myversion>0.1-SNAPSHOT</myversion>
</properties>


<modules>
<module>modulefolder</module>
</modules>
...
</project>

模块POM.xml

<project ...>
<modelVersion>4.0.0</modelVersion>


<parent>
<groupId>com.mydomain</groupId>
<artifactId>myprojectmodule</artifactId>
<version>${myversion}</version> <!-- This still needs to be set, but you can use properties from parent -->
</parent>


<groupId>se.car_o_liner</groupId>
<artifactId>vinno</artifactId>
<packaging>war</packaging>
<name>Vinno</name>
<!-- Note that there's no version specified; it's inherited from parent -->
...
</project>

你可以自由地将myversion更改为你想要的任何不是保留属性的东西。

eFox的答案适用于单个项目,但当我从另一个项目引用一个模块时(pom.xml仍然存储在我的.m2中,使用属性而不是版本)。

然而,如果你将它与flatten-maven-plugin结合使用,它就可以工作,因为它生成的是带有正确版本的poms,而不是属性。

我在插件定义中唯一更改的选项是outputDirectory,默认情况下它是空的,但我更喜欢在target中设置它,这是在我的.gitignore配置中设置的:

<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>flatten-maven-plugin</artifactId>
<version>1.0.1</version>
<configuration>
<updatePomFile>true</updatePomFile>
<outputDirectory>target</outputDirectory>
</configuration>
<executions>
<execution>
<id>flatten</id>
<phase>process-resources</phase>
<goals>
<goal>flatten</goal>
</goals>
</execution>
</executions>
</plugin>

插件配置放在父母pom.xml . xml文件中

从Maven 3.5.0开始,你可以使用${revision}占位符。该用法记录在这里:Maven CI友好版本

简而言之,父母pom看起来像这样(引用自Apache文档):

<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache</groupId>
<artifactId>apache</artifactId>
<version>18</version>
</parent>
<groupId>org.apache.maven.ci</groupId>
<artifactId>ci-parent</artifactId>
<name>First CI Friendly</name>
<version>${revision}</version>
...
<properties>
<revision>1.0.0-SNAPSHOT</revision>
</properties>
<modules>
<module>child1</module>
..
</modules>
</project>

孩子们像这样跳

<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.maven.ci</groupId>
<artifactId>ci-parent</artifactId>
<version>${revision}</version>
</parent>
<groupId>org.apache.maven.ci</groupId>
<artifactId>ci-child</artifactId>
...
</project>

你还可以必须使用Flatten Maven插件来生成pom文档,其中包含了用于部署的专用版本号。HowTo在链接的文档中有详细的说明。

@khmarbaise也写了一篇关于这个功能的不错的文章:Maven:没有版本的POM文件?

使用mvn -N versions:update-child-modules更新子pom的版本

https://www.mojohaus.org/versions-maven-plugin/examples/update-child-modules.html

<parent>
<groupId>com.dummy.bla</groupId>
<artifactId>parent</artifactId>
<version>0.1-SNAPSHOT</version>
</parent>


<groupId>com.dummy.bla.sub</groupId>
<artifactId>kid</artifactId>

你的意思是你想从B的pom的父块中删除版本,我认为你不能这样做,groupId, artifactId和version指定了父的pom坐标,你可以省略的是子版本。

It worked for me using BOM approach on parent pom.xml:


My scenario:
- parent pom.xml 0.0.0.1-SNAPSHOT
- sub-project1
- sub-project2 (sub-project1 is a dependency)


<properties>
<revision>0.0.0.1-SNAPSHOT</revision>
</properties>


<groupId>com.example</groupId>
<artifactId>commons</artifactId>
<packaging>pom</packaging>
<version>${revision}</version>
<name>commons</name>
<description>parent module of commons project</description>




<modules>
<module>sub-project1</module>
<module>sub-project2</module>
</modules>


<dependencyManagement>


<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<type>pom</type>
<version>2.6.4</version>
<scope>import</scope>
</dependency>


<dependency>
<groupId>com.example.commons</groupId>
<artifactId>sub-project1</artifactId>
<version>${revision}</version>
</dependency>
</dependencies>


</dependencyManagement>

子项目pom.xml可以从父项目继承${revision}编号,而且实际列出的依赖项不需要显式地提到标记

    <parent>
<groupId>com.example</groupId>
<artifactId>commons</artifactId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>


<groupId>com.example.commons</groupId>
<artifactId>sub-project2</artifactId>
<version>${revision}</version>
<name>sub-project2</name>
<description>implement sub-project2 </description>


    

<dependencies>
<dependency>
<groupId>com.example.commons</groupId>
<artifactId>sub-project1</artifactId>
</dependency>
       

</dependencies>
在Maven 3.8.4和windows机器上,这里是你必须做的从父pom继承版本 1:创建父pom,如下所示

          <groupId>com.example</groupId>
<artifactId>example</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
        

<modules>
<module>module-1</module>
<module>module-2</module>
<module>module-3</module>
</modules>
        

<name>example</name>
<url>https://www.example.com</url>
        

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<spring.boot.maven.plugin.version>2.5.7</spring.boot.maven.plugin.version>
<spring.boot.dependencies.version>2.5.7</spring.boot.dependencies.version>
<spring.cloud-version>2020.0.3</spring.cloud-version>
</properties>

Dependencies您想要获得子依赖项版本 来自他们的“依赖、管理”;标签;“scope"和“;type"标签是实现这个目标的关键

          <dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring.boot.dependencies.version}</version>
<scope>import</scope>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring.cloud-version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
你希望每个子元素都可用的依赖项会出现 “dependencies"标记< / p >
      <dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>2.7.0</version>
<scope>test</scope>
</dependency>
    

</dependencies>
    

<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring.boot.maven.plugin.version}</version>
</plugin>
</plugins>
</pluginManagement>
</build>
   

2:现在让我们看看子pom文件

<parent>
<artifactId>example</artifactId>
<groupId>com.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>


<artifactId>module-1</artifactId>


<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
注意,我没有指定版本,所以我从 父pom👇

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>