我如何告诉Maven使用最新版本的依赖关系?

在Maven中,依赖关系通常是这样设置的:

<dependency> <groupId>wonderful-inc</groupId> <artifactId>dream-library</artifactId> <version>1.2.3</version> </dependency> 

现在,如果您正在使用频繁发布的库,不断更新<version>标签可能会有些恼人。 有什么办法告诉Maven总是使用最新的可用版本(从版本库)?

注意: 这个答案只适用于Maven 2! 在6年前,Maven 3为了“可重复构build”而提到了LATESTRELEASE变种。

如果您始终想要使用最新版本,Maven有两个关键字可以用来替代版本范围。 您应该小心使用这些选项,因为您不再控制所使用的插件/依赖项。

当您依赖插件或依赖项时,可以使用LATEST或RELEASE的版本值。 最新引用特定工件的最新发布版本或快照版本,这是最近在特定存储库中部署的工件。 RELEASE是指存储库中的最后一个非快照版本。 一般来说,devise依赖于非特定版本的工件的软件不是最佳实践。 如果您正在开发软件,则可能需要使用RELEASE或LATEST作为便利,以便在发布第三方库的新版本时不必更新版本号。 发布软件时,应始终确保项目取决于特定版本,以减less不受您控制的软件版本影响构build或项目的可能性。 如果有的话,请谨慎使用最新和释放。

有关更多详细信息,请参阅Maven书籍的POM语法部分 。 或者在依赖版本范围上查看此文档,其中:

  • 方括号( [] )表示“closures”(含)。
  • 括号( () )表示“开放”(不包括)。

这里有一个例子说明各种选项。 在Maven仓库中,com.foo:my-foo具有以下元数据:

 <?xml version="1.0" encoding="UTF-8"?><metadata> <groupId>com.foo</groupId> <artifactId>my-foo</artifactId> <version>2.0.0</version> <versioning> <release>1.1.1</release> <versions> <version>1.0</version> <version>1.0.1</version> <version>1.1</version> <version>1.1.1</version> <version>2.0.0</version> </versions> <lastUpdated>20090722140000</lastUpdated> </versioning> </metadata> 

如果需要对该工件的依赖性,则可以使用以下选项(当然,也可以指定其他版本范围 ,只是在此显示相关的版本):

声明一个确切的版本(将永远parsing为1.0.1):

 <version>[1.0.1]</version> 

声明一个明确的版本(将永远parsing为1.0.1,除非发生冲突,当Maven将select一个匹配的版本):

 <version>1.0.1</version> 

声明所有1.x的版本范围(目前将parsing为1.1.1):

 <version>[1.0.0,2.0.0)</version> 

声明开放式版本范围(将parsing为2.0.0):

 <version>[1.0.0,)</version> 

声明版本为最新(将parsing为2.0.0)(从maven 3.x中删除)

 <version>LATEST</version> 

声明版本为RELEASE(将parsing为1.1.1)(从maven 3.x中删除):

 <version>RELEASE</version> 

请注意,默认情况下,您自己的部署将更新Maven元数据中的“latest”条目,但要更新“release”条目,则需要从Maven超级POM激活“release-profile”。 您可以使用“-Prelease-profile”或“-DperformRelease = true”


值得强调的是,任何允许Mavenselect依赖版本(LATEST,RELEASE和版本范围)的方法都可能会导致构build时间问题,因为后续版本可能会有不同的行为(例如,依赖项插件之前已经切换了默认值从真到假,结果令人困惑)。

因此,在发行版中定义精确版本通常是一个好主意。 正如Tim的回答指出的那样, maven-versions-plugin是一个更新依赖版本的方便工具,特别是版本:use-latest-versions和versions:use-latest-releases目标。

现在我知道这个话题已经很老了,但是阅读这个问题,OP提供了答案,似乎Maven Versions Plugin可能实际上是他的问题的一个更好的答案:

特别是可以使用以下目标:

  • 版本:use-latest-versions在pom中search所有已经是新版本的版本,并用最新版本replace它们。
  • 版本:use-latest-releases在pom中search所有非SNAPSHOT版本,这些版本是较新的版本,并用最新版本replace它们。
  • 版本:update-properties更新项目中定义的属性,以便它们对应于特定依赖项的最新可用版本。 如果一组依赖关系必须全部被locking到一个版本,这可能很有用。

还提供了以下其他目标:

  • 版本:display-dependency-updates扫描项目的依赖关系,并生成具有可用更新版本的依赖项的报告。
  • 版本:display-plugin-updates扫描一个项目的插件,并生成一个报告,这些插件有更新的版本可用。
  • 版本:update-parent更新项目的父节,以便引用最新的可用版本。 例如,如果您使用公司根POM,那么如果您需要确保使用最新版本的公司根POM,则此目标会很有帮助。
  • 版本:update-child-modules更新项目的子模块的父节,以便版本匹配当前项目的版本。 例如,如果聚合器pom也是其聚合项目的父项,并且子项和父项版本不同步,则此mojo可以帮助修复子模块的版本。 (注意,如果你的项目因为版本不匹配而无法编译,那么你可能需要用-N选项来调用Maven来运行这个目标)。
  • 版本:locking快照searchpom中所有的“-snapshot”版本,并使用该“-snapshot”的当前时间戳版本replace它们,例如-20090327.172306-4
  • 版本:unlock-snapshots在pom中search所有时间戳locking的快照版本,并用-SNAPSHOTreplace它们。
  • 版本:resolve-ranges使用版本范围查找依赖关系,并将范围parsing为正在使用的特定版本。
  • 版本:use-releases在pom中search已发布的所有“SNAPSHOT”版本,并将其replace为相应的发行版本。
  • 版本:use-next-releases在pom中search所有非SNAPSHOT版本,这些版本是新版本,并用下一个发行版本replace它们。
  • 版本:use-next-versions在pom中search所有已经是新版本的版本,并用下一个版本replace它们。
  • 版本:提交删除pom.xml.versionsBackup文件。 形成内置的“穷人SCM”的一半。
  • 版本:恢复从pom.xml.versionsBackup文件恢复pom.xml文件。 形成内置的“穷人SCM”的一半。

只是想我会把它包括在内以备将来参考。

请看这个页面 (“依赖版本范围”一节)。 你可能想要做的是类似的

 <version>[1.2.3,)</version> 

这些版本范围在Maven2中实现。

与其他人不同,我认为有很多原因可能总是希望获得最新版本。 特别是如果您正在进行连续部署(我们有时候一天有5个版本),并且不想执行多模块项目。

我所做的就是让Hudson / Jenkins为每一个构build做下面的事情:

 mvn clean versions:use-latest-versions scm:checkin deploy -Dmessage="update versions" -DperformRelease=true 

这是我使用版本插件和SCM插件来更新依赖关系,然后检查它到源代码pipe理。 是的,我让我的CI做SCM校验(你必须为maven发布插件做任何事情)。

你会想要设置版本插件只更新你想要的:

  <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>versions-maven-plugin</artifactId> <version>1.2</version> <configuration> <includesList>com.snaphop</includesList> <generateBackupPoms>false</generateBackupPoms> <allowSnapshots>true</allowSnapshots> </configuration> </plugin> 

我使用发布插件来执行发布,以处理-SNAPSHOT并validation是否有发布版本的-SNAPSHOT(这很重要)。

如果您按照自己的要求进行操作,您将获得所有快照构build的最新版本以及发布版本的最新版本。 你的构build也是可重复的。

更新

我注意到了一些评论,询问这个工作stream程的一些细节。 我会说我们不再使用这个方法了,maven版本插件的一个重要原因是bug,总的来说本质上是有缺陷的。

这是有缺陷的,因为运行版本插件来调整版本所有现有的版本需要存在的POM正确运行。 这是版本插件无法更新到最新版本的任何东西,如果它无法find在POM中引用的版本。 这实际上是相当烦人的,因为我们经常清理旧版本的磁盘空间的原因。

真的,你需要一个单独的工具来调整版本(所以你不依赖于POM文件来正确运行)。 我用Bash的低级语言写了这样一个工具。 该脚本将更新像版本插件的版本,并检查POM回到源代码pipe理。 它的运行速度比mvn版插件快100倍。 不幸的是,它不是以公开的方式写的,但是如果人们有兴趣,我可以把它写出来,并把它放在一个主题或github。

回到工作stream程中,有人问我们这是做什么的:

  1. 我们在自己的仓库里有20个左右的项目,并有自己的jenkins工作
  2. 当我们发布maven版本插件的时候使用。 这个工作stream程在插件的文档中有介绍。 maven发布插件sorting(我很友善),但它确实有效。 有一天,我们计划用更优化的东西来取代这种方法。
  3. 当其中一个项目被释放时,jenkins会运行一个特殊的工作,我们会调用更新所有版本的工作(jenkins知道它的发布是一个复杂的方式,部分原因是maven jenkins发布插件也相当糟糕)。
  4. 更新所有版本的作业都知道所有的20个项目。 它实际上是一个聚合器pom,以依赖顺序在模块部分中的所有项目都是特定的。 Jenkins运行我们的魔术groovy / bash foo,它将把所有的项目更新到最新的版本,然后检查poms(再次根据模块部分以依赖顺序完成)。
  5. 对于每个项目,如果POM已经改变(由于版本的变化,在一些依赖),它被检入,然后我们立即平jenkins运行该项目相应的工作(这是为了保存构build依赖性顺序,否则你是在摆布SCM轮询调度器)。

在这一点上,我认为这是一个好东西,无论如何发行版和汽车版是一个单独的工具从你的一般构build。

现在你可能会认为maven是因为上面列出的问题而糟糕透了,但是这对于一个没有声明性的,易于parsing可扩展语法(又名XML)的构build工具来说实际上是相当困难的。

事实上,我们通过命名空间添加自定义XML属性来帮助提示bash / groovy脚本(例如,不要更新这个版本)。

依赖关系语法位于依赖版本要求规范文档中。 这是完整的:

依赖关系的version元素定义了版本需求,用于计算有效的依赖版本。 版本要求具有以下语法:

  • 1.01.0 “软”要求(只是build议,如果它匹配所有依赖的其他范围)
  • [1.0][1.0] “硬”要求
  • (,1.0] :x <= 1.0
  • [1.2,1.3] :1.2 <= x <= 1.3
  • [1.0,2.0) :1.0 <= x <2.0
  • [1.5,) :x> = 1.5
  • (,1.0],[1.2,) :x <= 1.0或x> = 1.2; 多组逗号分隔
  • (,1.1),(1.1,) :这不包括1.1(例如,如果已知不与该库合作)

在你的情况下,你可以做一些像<version>[1.2.3,)</version>

你可能依赖于在开发过程中明显改变的开发版本吗?

不必增加开发版本的版本,只需使用在必要时覆盖的快照版本,这意味着您不必在每次较小的更改时都更改版本标签。 像1.0-SNAPSHOT …

但是,也许你正在努力实现其他的东西;)

谁使用最新的,请确保你有-U,否则最新的快照将不会被拉。

 mvn -U dependency:copy -Dartifact=com.foo:my-foo:LATEST // pull the latest snapshot for my-foo from all repositories 

在提出这个问题的时候,maven中有一些版本范围的问题,但是这些问题已经在新版本的maven中解决了。 本文很好地捕获了版本范围的工作原理和最佳实践,以更好地理解maven如何理解版本: https : //docs.oracle.com/middleware/1212/core/MAVEN/maven_version.htm#MAVEN8855

事实上,即使在3.x它仍然有效,令人惊讶的项目build设和部署。 但是LATEST / RELEASE关键字在m2e和eclipse中造成了问题,ALSO项目依赖于通过LATEST / RELEASE部署的依赖,无法识别版本。

如果您尝试将版本定义为属性,则会导致问题,并在其他位置引用它。

所以,如果可以的话,结论就是使用versions-maven-plugin 。

有时你不想使用版本范围,因为它似乎是“慢”来解决你的依赖关系,特别是当有持续交付的地方,并有大量的版本 – 主要是在重大的发​​展。

一种解决方法是使用versions-maven-plugin 。 例如,你可以声明一个属性:

 <properties> <myname.version>1.1.1</myname.version> </properties> 

并将versions-maven-plugin添加到您的pom文件中:

 <build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>versions-maven-plugin</artifactId> <version>2.3</version> <configuration> <properties> <property> <name>myname.version</name> <dependencies> <dependency> <groupId>group-id</groupId> <artifactId>artifact-id</artifactId> <version>latest</version> </dependency> </dependencies> </property> </properties> </configuration> </plugin> </plugins> </build> 

然后,为了更新依赖关系,你必须执行这个目标:

 mvn versions:update-properties validate 

如果有一个比1.1.1更新的版本,它会告诉你:

 [INFO] Updated ${myname.version} from 1.1.1 to 1.3.2