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


188

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

A / 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-SNAPSHOTA/pom.xml。但是,如果我<version>0.1-SNAPSHOT</version>B/pom.xml父项下删除,则maven会抱怨父项缺少版本。

有没有一种我可以使用的方法${project.version}或类似的方法来避免01.-SNAPSHOT两种情况都出现?


4
恐怕您必须为此等待Maven 3.1。
感知2012年



1
上面的链接已移动。最终状态为“已关闭/无法修复” issues.apache.org/jira/browse/MNG-624
jocull

Answers:


86

编辑:自Maven 3.5.0以来,使用${revision}占位符对此有一个不错的解决方案。有关详细信息,请参见FrVaBe的答案。对于以前的Maven版本,请参见下面的原始答案。


不,没有。您始终必须指定父母的版本。幸运的是,它继承了大多数情况下所需的模块版本。此外,Maven Release Plugin会自动更改该父级的版本声明,因此-实际上-只要使用Maven Release Plugin进行发布或仅更改版本,就可以在2个地方拥有版本不是问题。

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


3
现在,您可以${revision}为此使用占位符。见我的回答;-)
FrVaBe

2
现在已经过时了-在这里查看@FrVaBe的答案:stackoverflow.com/a/51969067/514483
抢劫

@FrVaBe如果我们嵌套了具有不同版本的父母该怎么办?我们不能在那里使用一个$ {revision}属性,这还不够。
halil

@halil问题是关于从父级继承一个版本,目标是在两个工件中具有相同的版本。如果您具有不同版本(在继承层次结构中)的不同父级,则可能不会使它们具有相同的版本。因此,我不完全理解该评论。
FrVaBe

86

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>

儿童绒球

<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不再允许这种配置。


2
是的,恐怕Maven并非以这种方式工作,最好只将版本放在sub pom.xml中。无论如何,maven版本插件并不真正在乎那里的版本。
圣杰

7
3.0.5可以正常工作。您应该将<properties>放在最顶部。
2013年

7
它在3.2.3中工作。<properties>的位置无关紧要。但是,您会收到警告:'version' contains an expression but should be a constant.
kapex 2014年

4
请注意这一点。当您的项目被另一个项目引用时,此功能不起作用。该属性将无法解析,并将按字面意义处理(即$ {my.version})。解决依赖关系时,这将导致失败。
spekdrum '16

2
我也已经使用了很长一段时间,它对于单个多模块项目工作得很好(当前在maven 3.3.9中)。但是,一旦您的项目成为另一个项目的依赖项,事情就会变得棘手。我真的建议采纳下面@pay提出的建议。
巧妙的2016年

80

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

$ mvn versions:set -DgenerateBackupPoms=false

(在您的根/父pom文件夹中执行此操作)。

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


17
您也可以添加-DnewVersion = {versionToBeUpdated}以避免交互输入。
Mukesh

1
我认为这是最好的答案,它可以在不中断子项目的情况下自动进行版本更改(没有父pom就无法引用)。
塔雷克

对!这就是答案。🙌–
aaiezza

如果子pom版本和父pom版本最初不同,请先对其进行更新以匹配, mvn versions:update-child-modules 否则将跳过所有子pom版本。
Gautam Tadigoppula

75

从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也写了一篇有关此功能的不错的blob帖子:Maven:POM文件中没有版本吗?


我按照您的描述配置了我的项目,但是没有“ Flatten Maven插件”,并且似乎可以按预期工作,这可能吗?我也遇到了Maven 3.2.1的错误,但是Maven 3.3.9+似乎可以正常工作。
最多

@Max这取决于您定义为“预期工作”的内容。我想构建会通过,但是安装/部署到存储库可能不是一个好主意,因为子pom中没有版本号,而只有一个占位符(请参阅文档
FrVaBe

我在具有默认属性(<properties> <version> 0.1-default </ version> </ properties>的父pom中使用<version> $ {revision} </ version>。子poms也使用<version> $ {revision} < / version>。我使用“ mvn clean install -Drevision = 0.1。$ {bamboo.buildNumber}”。当我扫描部署日志时,所有内容均设置为0.1.820,而日志中甚至没有包含0.1-default(820是buildNumber)。当我扫描生成的jar时,我在清单中看到“ Implementation-Version:0.1.820”,在pom.properties文件中看到“ version = 0.1.820”。pom文件本身具有<version> $ {revision} </ version>。那么,我觉得还好吗?
Max

1
@Max尝试将版本${revision} 位于pom(在maven存储库中)的jar解析为另一个项目中的依赖项。我认为这不会奏效。
FrVaBe

这很有用,除了发布时。${revision}用新版本替换版本标签
Mike D

21

正如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为非保留属性的任何内容。


3
当从另一个项目引用模块时,Maven不会解析该属性。那是正常的吗?
LeoLozes

我认为这个问题可能值得其提出,而不是在这种评论中。没有看到您的代码,我只能疯狂地猜测。
eFox

@LeoLozes您是否解决了问题(另一个项目的引用模块)?
Morteza Malvandi

@MortezaMalvandi是的!我的回答在底部:)
LeoLozes

2
Maven 3.6.0对此配置发出警告:“强烈建议修复这些问题,因为它们会威胁到构建的稳定性。” “因此,未来的Maven版本可能不再支持构建此类格式错误的项目。”
d2k2,19年

17

您还可以使用:

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

更新您的POM中的版本号。


10

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

但是,如果将其与结合使用,则它可以工作flatten-maven-plugin,因为它会生成具有正确版本而非属性的pom。

我在插件定义中更改的唯一选项是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中



0
<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和版本指定了父pom坐标的版本,您可以忽略的是孩子的版本。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.