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

She*_*jie 161 inheritance maven

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

A/pom.xml中:

<groupId>com.dummy.bla</groupId>
<artifactId>parent</artifactId>
<version>0.1-SNAPSHOT</version>
<packaging>pom</packaging>
Run Code Online (Sandbox Code Playgroud)

在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>
Run Code Online (Sandbox Code Playgroud)

我希望B从父级继承该版本,所以我需要放置的唯一位置0.1-SNAPSHOTA/pom.xml.但是,如果删除了<version>0.1-SNAPSHOT</version>B/pom.xml下父节,Maven的抱怨缺少的版本父.

有没有办法可以使用${project.version}或类似的东西,以避免01.-SNAPSHOT在两个poms?

Yan*_*lea 82

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>
Run Code Online (Sandbox Code Playgroud)

孩子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>
Run Code Online (Sandbox Code Playgroud)

我对我的一个项目使用了这个技巧,没有特别的问题,除了maven在构建开始时记录了很多警告,这不是很优雅.

编辑

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

  • 对于3.0.5工作正常.你应该把<properties>放在最顶层. (7认同)
  • 它适用于3.2.3.<properties>的位置无关紧要.你会得到一个警告:''version'包含一个表达式,但应该是一个常量 (7认同)
  • 请小心这个.当您的项目被另一个项目引用时,这不起作用.该属性将无法解析,将按字面处理(即$ {my.version}).这将在解决依赖关系时导致失败. (4认同)
  • 是的,我担心maven的设计不是那么好的,更好的是坚持将版本放在sub pom.xml中.无论如何,maven发布插件并不真正关心那里的版本. (2认同)
  • 我一直在使用它已经有一段时间了,它对于单个多模块项目来说效果很好(目前使用maven 3.3.9).但是,只要您的项目成为另一个项目的依赖项,事情就会变得非常棘手.我真的建议采用以下@pay提出的建议. (2认同)

小智 72

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

$ mvn versions:set -DgenerateBackupPoms=false
Run Code Online (Sandbox Code Playgroud)

(在你的root/parent pom文件夹中执行此操作).

解析您的POM,并询问您要设置的版本.

  • 您还可以添加-DnewVersion = {versionToBeUpdated}以避免以交互方式输入. (15认同)

Mic*_*ski 70

编辑:从Maven 3.5.0开始,使用${revision}占位符有一个很好的解决方案.有关详细信息,请参阅FrVaBe的答案.对于以前的Maven版本,请参阅下面的原始答案.


不,没有.您始终必须指定父版本.幸运的是,它被继承为模块的版本,在大多数情况下是可取的.此外,这个父母的版本声明是由Maven Release Plugin自动提出的,所以 - 实际上 - 只要你使用Maven Release Plugin发布版本或只是碰撞版本,你就不会有2个版本的问题.

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

  • Nowadys你可以使用`$ {revision}`占位符.看我的答案;-) (3认同)
  • 这已经过时了 - 请点击@ FrVaBe的答案:/sf/answers/3637834721/ (2认同)

FrV*_*aBe 49

从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>
Run Code Online (Sandbox Code Playgroud)

而这孩子就像这样

<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>
Run Code Online (Sandbox Code Playgroud)

您还必须使用Flatten Maven插件生成包含用于部署的专用版本号的pom文档.HowTo记录在链接文档中.

另外@khmarbaise写了一篇关于这个功能的好帖子:Maven:没有版本的POM文件?

  • @Ralf 几年前我就不再认为版本范围是个好主意了。你无法用它获得可重现的构建。所以我不再使用它们了。 (3认同)
  • @Max这取决于你定义的“按预期工作”。我猜构建会通过,但安装/部署到存储库可能不是个好主意,因为子 pom 中没有版本号,只有占位符(请参阅[文档](https://maven.apache.org/maven -ci-Friendly.html#Install_.2F_Deploy)) (2认同)
  • @MikeD 在发布的版本中没有占位符很可能就是您想要的。否则,存储库管理器(甚至 Maven 本身)将永远无法识别已发布的版本。 (2认同)

eFo*_*Fox 20

正如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>
Run Code Online (Sandbox Code Playgroud)

模块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>
Run Code Online (Sandbox Code Playgroud)

您可以随意更改myversion为您想要的任何不属于保留的属性.

  • Maven 3.6.0 对此配置给出警告:“强烈建议修复这些问题,因为它们威胁到您构建的稳定性。” “出于这个原因,未来的 Maven 版本可能不再支持构建这种格式错误的项目。” (4认同)
  • 最有可能归功于https://issues.apache.org/jira/browse/MNG-2199 (2认同)
  • 从其他项目引用模块时,Maven无法解析该属性.这是正常的吗? (2认同)

小智 17

你也可以使用:

$ mvn release:update-versions -DdevelopmentVersion={version}
Run Code Online (Sandbox Code Playgroud)

更新POM中的版本号.


Leo*_*zes 9

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>
Run Code Online (Sandbox Code Playgroud)

插件配置位于父pom.xml中