不分散版本号的maven项目层次结构

Posted

技术标签:

【中文标题】不分散版本号的maven项目层次结构【英文标题】:Hierarchy of maven projects without scattering the version number 【发布时间】:2010-09-29 18:26:44 【问题描述】:

如果您将Maven2 用作包含许多具有相同版本号的工件的项目的构建系统,则生成的构建版本会分散在所有 pom.xml 中。其中许多甚至两次 - 在人工制品本身的版本标签和父版本标签中。因此,您必须在每次版本切换时更改并签入所有 pom.xml 的新版本。这有点烦人,特别是如果您必须同时编写多个错误修复和开发版本的代码。有办法解决吗?

澄清:我的问题是,随着时间的推移,您在源代码控制系统中获得的每个 pom.xml 的许多版本仅在 pom 的版本号和/或父 pom 的版本号上有所不同。理想情况下,您应该只需要在添加依赖项或其他内容时更改 pom。

例如,您有一个项目,其中包含工件 foo-pom(所有的父 pom)、foobar-jar、foobaz-jar 和 foo-war。在第一个版本中,版本是 1.0 - 它出现在每个 pom.xml 中。在第二个版本中,版本是 1.1 - 它再次出现在每个 pom.xml 中。因此,您必须更改每个 pom.xml - 如果您尽可能频繁地发布,这很烦人。

更新:如果您认为这很重要:已经在考虑不必指定父版本。请转至maven JIRA issue 并为它投票,以使其受到更多关注,并更有可能在即将发布的版本中作为增强功能添加。您需要为此创建/拥有一个 JIRA 登录名。

another *** Question 基本上是同样的问题。

【问题讨论】:

【参考方案1】:

在我的项目中,我遇到了这样的问题。为了减少版本的数量,我在父 pom.xml 中定义了一些属性,这些属性对应于每个模块的版本:

<properties>
    <project-version>1.0.0</project-version>
    <!-- Same version than the parent for the module 'commons' -->
    <project-commons-version>$project-version</project-commons-version>
    <!-- A specific version for the 'business' module -->
    <project-business-version>1.0.1</project-business-version>
    ...

然后,在每个模块的 pom.xml 中,我使用这些属性。 问题是我必须在这个 pom.xml 中明确输入父版本的版本。 例如,在我的业务 pom.xml 中,我有:

<project>
  <modelVersion>4.0.0</modelVersion>
  <!-- I must indicate the version of the parent -->
  <parent>
    <groupId>my.project</groupId>
    <artifactId>parent</artifactId>
    <version>1.0.0</version>
  </parent>
  ...
  <dependencies>
    <!-- However, in my dependencies, I use directly the properties defined in the parent's pom.xml -->
    <dependency>
      <groupId>my.project</groupId>
      <artifactId>project-persistence</artifactId>
      <version>$project-persistence-version</version>
    </dependency>

但是,我真的建议您查看release plugin,它将为您修改所有版本号。

【讨论】:

这也是我们使用的模式——除了发布插件。我想知道您是否可以以某种方式避免将父版本放在每个 pom.xml 中。但似乎你必须忍受源代码管理中的许多版本的 pom,它们仅因父版本不同而不同。 我觉得这种方式可以补充Maven版本插件:mojo.codehaus.org/versions-maven-plugin 可以自动增加子项目中的parent.version标签;查看版本:更新子模块目标。【参考方案2】:

article 是否为您的问题提供了解决方案?

这个想法是在父 pom.xml 中将整个项目的版本号声明为一个属性,即“aversion”(双关语)。父 pom 自己的版本号可以是任何东西,只要它以“SNAPSHOT”结尾。

子模块的版本是通过 $aversion 属性指定的。孩子对其父母版本的引用是硬编码的。但是,由于父 pom 的版本是 SNAPSHOT,子模块将看到父 pom 中的更改。特别是,如果父 pom 更改了 $aversion 的值,子级将看到更改。

根据 cmets,这不是一个完美的解决方案。

而发布插件并没有解决真正的问题:合并。 到处都有版本号的无穷无尽的副本意味着在将分支重新组合在一起时会产生很多冲突。

注意:

对于 Maven 2.0.9(最新版本 - 2008 年 4 月),我只是从各个模块中省略了版本元素,因为它们将从其父模块继承版本。如果您的模块与其父模块共享相同的 groupId,这也适用于 groupId。

【讨论】:

VonC 是正确的,如果您希望它们与父级相同,您可以省略您的 pom 的 groupId 和 artifactId。但是挑战仍然存在,即使在多模块分层构建中,您也必须明确声明父版本的版本。【参考方案3】:

这是一个可能解决问题的 maven 扩展的想法。 目前,您必须在 pom.xml 中编写工件和父 pom 的版本。已经有一种方法可以为父 pom 提供绝对位置:

<parent>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>my-parent</artifactId>
    <version>2.0</version>
    <relativePath>../my-parent</relativePath>
</parent>

如果你允许省略父版本和这个 pom 的版本,只要 maven 能够通过相对路径访问父 pom,你就完成了。该版本仅在父 pom 中提及,其他地方未提及。

【讨论】:

【参考方案4】:

我在使用 Maven 2 构建的大型系统时遇到了类似的问题。

在我看来,典型的多模块结构的缺点是所有模块 必须共享相同的版本。这确实很烦人:即使你的 下一个版本仅包含 foobar-jar 中的错误修复,您需要 随处更改全局版本(手动或使用 maven-release-plugin) 并推出每个组件的新版本。就我而言,我构建了各种 WAR/EAR 应用程序,所以我的客户会问我为什么要同时提供 app1app2 的新版本,而应该只影响 app1

相反的方法是将每个组件作为一个独立的组件进行管理 项目,有自己的独立版本。这更灵活,因为它 允许部分发布,但您现在需要跟踪所有这些版本 手动(知道您的下一次交付将包含哪些版本,制作 确保内部依赖是一致的,等等)。这可以很快 成为大型应用程序的噩梦。

我长期以来一直在思考一种将这两种方法结合起来的方法:独立版本的灵活性,同时又不放弃系统的全局一致性。我尝试了与 romaintaz 相同的方法,但遇到了同样的问题。最后,我想出了这个主意: http://out-println.blogspot.com/2008/10/maven-modules-with-independent-versions.html.

认为它是“实验性的”,因为我最终没有去现场尝试(出于非技术原因)。但我认为它可以解决问题。

【讨论】:

博客链接失效,能否提供新链接?【参考方案5】:

有another *** thread that also covers this topic that you might want to look at。

简而言之,使用继承时不必指定父版本 already being considered. Please go over to JIRA and give it a vote bump 以使其更受关注,并且更有可能在即将发布的版本中作为增强功能添加。

【讨论】:

10 多年后的今天【参考方案6】:

在解决 maven issue 之前,这是另一个轻量级的解决方法。在一个大型项目中,我们不再将 pom.xml 本身放在版本控制中,而是将 pom-template.xml 仅包含版本号的占位符。从版本控制更新项目树后,您需要运行一个小 ant 脚本,在每个目录中生成实际的 pom.xml。这很烦人,但比忍受所有那些烦人的 pom 版本更烦人。

【讨论】:

【参考方案7】:

我们确实有这个问题。我们有大量(大约 10 个)不同的项目,其中一些相互依赖。包含项目的文件夹有一个用于整个项目集的父 pom。每次我们创建一个新分支时,我们都必须进入每个 pom 文件来更改 元素以及父级的 元素,所有这些编辑都很烦人。

在阅读了这个问题和这里的答案后,我意识到情况已经没有希望了。每个项目都可以从父 pom 继承 元素,这样很容易消除,但我们显然不能为 继承

不幸的是,我忘了告诉我的同事这是不可能的,所以他修好了。他的解决方案是在父 pom 文件中添加一个属性:

<properties><currentVersion>2.6.1-SNAPSHOT</currentVersion></properties>

然后在子 pom 文件中我们这样声明父版本标签:

<version>$currentVersion</version>

我不知道为什么会这样。我看不出它如何在不指定版本号的情况下找到正确的父 pom。但对我来说(maven 版本 1.5.0_22)它正在工作。

【讨论】:

而不是这个,你可能想考虑使用发布插件。它将帮助您更改版本号。 是的,Jakrabbit,除了两件事。 (1) 我们发布过程的其他特点使得使用发布插件变得困难,并且 (2) 正如我所解释的,我们不再有问题了。 为什么这个答案被否决了?这是一个很好的解决方案(在父级中,我有 &lt;properties&gt;&lt;currentVersion&gt;$version&lt;/currentVersion&gt;&lt;/properties&gt; 对我来说它正在工作

以上是关于不分散版本号的maven项目层次结构的主要内容,如果未能解决你的问题,请参考以下文章

maven统一修改项目版本号

maven基础

Maven安装:? - 如何创建一个发布候选?

如何使用 Maven 发布不同版本号的子模块?

清理 Maven 依赖管理

了解eclipse maven依赖层次结构