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

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

现在,如果您正在使用频繁发布的库,不断更新 <version> 标记可能会有些烦人。有没有办法告诉 Maven 始终使用最新的可用版本(来自存储库)?

有帮助吗?

解决方案

笔记:

这个答案仅适用于 Maven 2!其中提到的 LATESTRELEASE 元版本 “为了可重现的构建”,已在 Maven 3 中被删除, ,6年多前。请参考这个 Maven 3 兼容解决方案.


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

当您依赖插件或依赖项时,可以使用 LATEST 或 RELEASE 的版本值。LATEST 是指特定工件的最新发布版本或快照版本,即特定存储库中最近部署的工件。RELEASE 指存储库中的最后一个非快照版本。一般来说,设计依赖于工件的非特定版本的软件并不是最佳实践。如果您正在开发软件,为了方便起见,您可能希望使用 RELEASE 或 LATEST,以便在发布新版本的第三方库时不必更新版本号。当您发布软件时,您应该始终确保您的项目依赖于特定版本,以减少您的构建或项目受到不受您控制的软件版本影响的机会。如果有的话,请谨慎使用 LATEST 和 RELEASE。

请参阅 Maven 书中的 POM 语法部分 更多细节。或者查看此文档 依赖项版本范围, , 在哪里:

  • 方括号 ( [ & ] )指“关闭”(包括在内)。
  • 括号( ( & ) ) 表示“开放”(独占)。

这是一个说明各种选项的示例。在 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>

如果需要对该工件的依赖,您有以下选项(其他 版本范围 当然可以指定,这里只显示相关的):

声明确切的版本(始终解析为 1.0.1):

<version>[1.0.1]</version>

声明一个显式版本(除非发生冲突,否则将始终解析为 1.0.1,此时 Maven 将选择匹配的版本):

<version>1.0.1</version>

声明所有 1.x 的版本范围(当前将解析为 1.1.1):

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

声明一个开放式版本范围(将解析为 2.0.0):

<version>[1.0.0,)</version>

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

<version>LATEST</version>

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

<version>RELEASE</version>

请注意,默认情况下,您自己的部署将更新 Maven 元数据中的“最新”条目,但要更新“发布”条目,您需要从 Maven超级POM. 。您可以使用“-Prelease-profile”或“-DperformRelease=true”来执行此操作


值得强调的是,任何允许 Maven 选择依赖项版本(LATEST、RELEASE 和版本范围)的方法都可能让您面临构建时间问题,因为更高版本可能有不同的行为(例如,依赖项插件之前已切换了默认值)值从 true 到 false,结果令人困惑)。

因此,在发行版中定义确切的版本通常是一个好主意。作为 蒂姆的回答 指出, maven 版本插件 是一个用于更新依赖版本的方便工具,特别是 版本:使用最新版本版本:使用最新版本 目标。

其他提示

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

特别是以下目标可能有用:

  • 版本:使用最新版本 在 POM 中搜索所有版本 这是较新的版本和 用最新的替换它们 版本。
  • 版本:使用最新版本 在 pom 中搜索所有非 SNAPSHOT 更新的版本 释放并将它们替换为 最新版本。
  • 版本:更新属性 更新中定义的属性 项目,以便它们对应于 最新版本 特定依赖项。这可以是 如果一组依赖项很有用 必须全部锁定到一个版本。

还提供了以下其他目标:

  • 版本:显示依赖项更新 扫描项目的依赖项和 生成一份报告 具有较新的依赖项 提供版本。
  • 版本:显示插件更新 扫描项目的插件和 生成这些插件的报告 有更新的版本可用。
  • 版本:更新父级 更新项目的父部分,以便 它引用了最新的 可用版本。例如,如果 您使用企业根 POM,这 如果需要,目标可能会有所帮助 确保您使用的是最新的 企业根 POM 的版本。
  • 版本:更新子模块 更新 项目的子模块,因此 version 与 当前项目。例如,如果你 有一个聚合器 POM,它也是 它的项目的父级 聚合和子项和 父版本不同步,这 Mojo 可以帮助修复 子模块。(请注意,您可能需要 使用 -N 选项调用 Maven 为了运行这个目标,如果你的 项目损坏得如此严重,以至于它 由于版本原因无法构建 不匹配)。
  • 版本:锁定快照 在 pom 中搜索所有 -SNAPSHOT 版本,并将它们替换为 该版本的当前时间戳版本 -快照,例如-20090327.172306-4
  • 版本:解锁快照 在 POM 中搜索所有时间戳 锁定的快照版本和替换 他们与 -SNAPSHOT.
  • 版本:解析范围 使用版本范围查找依赖项,并 将范围解析为特定的 正在使用的版本。
  • 版本:使用版本 在 pom 中搜索所有 -SNAPSHOT 版本 已发布并替换 它们具有相应的版本 版本。
  • 版本:使用下一个版本 在 pom 中搜索所有非 SNAPSHOT 更新的版本 释放并将它们替换为 下一个发布版本。
  • 版本:使用下一个版本 在 POM 中搜索所有版本 这是较新的版本和 将它们替换为下一个版本。
  • 版本:提交 删除 pom.xml.versionsBackup 文件。形成内置的“穷人SCM”的一半。
  • 版本:恢复 从 POM.xml 文件恢复 pom.xml.versions备份文件。形式 内置“穷人”的一半 SCM”。

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

请看一下 这一页 (“依赖版本范围”部分)。你可能想做的是

<version>[1.2.3,)</version>

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

与其他人不同,我认为您可能有很多原因 总是想要最新的 版本。特别是如果您正在进行持续部署(我们有时一天内发布 5 个版本)并且不想进行多模块项目。

我所做的是让 Hudson/Jenkins 对每个构建执行以下操作:

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

也就是说,我使用版本插件和 scm 插件来更新依赖项,然后将其签入源代码管理。是的,我让我的 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 并验证是否存在 -SNAPSHOT 的发布版本(这很重要)。

如果您执行我所做的操作,您将获得所有快照版本的最新版本和发布版本的最新发行版本。您的构建也将是可复制的。

更新

我注意到一些评论询问了此工作流程的一些细节。我想说的是,我们不再使用这种方法,主要原因是 Maven 版本插件存在缺陷,并且通常存在固有缺陷。

它是有缺陷的,因为要运行版本插件来调整版本,所有现有版本都需要存在才能使 pom 正确运行。也就是说,如果版本插件找不到 pom.xml 中引用的版本,则它无法更新到任何内容的最新版本。这实际上相当烦人,因为我们经常出于磁盘空间原因清理旧版本。

实际上,您需要一个来自 Maven 的单独工具来调整版本(这样您就不需要依赖 pom 文件来正确运行)。我用 Bash 等低级语言编写了这样一个工具。该脚本将像版本插件一样更新版本,并将 pom 检查回源代码管理。它的运行速度也比 mvn versions 插件快 100 倍。不幸的是,它不是以供公众使用的方式编写的,但如果人们感兴趣,我可以这样做并将其放在 gist 或 github 中。

回到工作流程,因为一些评论询问这就是我们所做的:

  1. 我们在自己的存储库中有 20 个左右的项目,有自己的詹金斯工作
  2. 当我们发布的时候会使用maven发布插件。插件的文档中介绍了其工作流程。Maven 发布插件有点糟糕(我很友善),但它确实有效。有一天,我们计划用更优化的方法替换这种方法。
  3. 当其中一个项目发布时,jenkins 运行一项特殊作业,我们将调用更新所有版本作业(jenkins 如何知道它的版本是一种复杂的方式,部分原因是 Maven jenkins 发布插件也非常糟糕)。
  4. 更新所有版本作业了解所有 20 个项目。它实际上是一个聚合器 pom,用于按依赖顺序指定模块部分中的所有项目。Jenkins 运行我们神奇的 groovy/bash foo,它会将所有项目更新到最新版本,然后签入 poms(再次根据模块部分按依赖顺序完成)。
  5. 对于每个项目,如果 pom 已更改(由于某些依赖项中的版本更改),则将其签入,然后我们立即 ping jenkins 以运行该项目的相应作业(这是为了保留构建依赖项顺序,否则您将受到怜悯SCM 轮询调度程序)。

在这一点上,我认为无论如何,将发布版和自动版作为独立于常规构建的工具是一件好事。

现在你可能会认为 Maven 有点糟糕,因为上面列出的问题,但对于没有易于解析的声明性的构建工具来说,这实际上是相当困难的 可扩展的 语法(又名 XML)。

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

依赖语法位于 依赖项 版本 要求 规范 文档。这是为了完整性:

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

  • 1.0:1.0 的“软”要求(仅是建议,如果它与依赖项的所有其他范围匹配)
  • [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 中它仍然有效,令人惊讶的是项目的构建和部署。但是 LATEST/RELEASE 关键字导致 m2e 和 eclipse 到处出现问题,而且项目依赖于通过 LATEST/RELEASE 部署的依赖项,无法识别版本。

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

所以结论是使用 版本-maven-插件 如果可以的话。

有时您不想使用版本范围,因为它们似乎解决您的依赖关系“缓慢”,特别是当持续交付到位并且有大量版本时 - 主要是在繁重的开发期间。

一种解决方法是使用 版本-maven-插件. 。例如,您可以声明一个属性:

<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

如果你希望 Maven 应该使用最新版本的依赖项,那么你可以使用 版本 Maven 插件 以及如何使用这个插件,Tim 已经给出了很好的答案,请关注他的 回答.

但作为一名开发人员,我不会推荐这种做法。为什么?

为什么已经给出了答案 帕斯卡·蒂文特 在问题的评论中

我真的不建议这种做法(也不使用版本范围) 为了构建可重复性。突然开始的构建 由于未知原因失败比手动更新更烦人 版本号。

我会推荐这种类型的练习:

<properties>
    <spring.version>3.1.2.RELEASE</spring.version>
</properties>

<dependencies>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
    </dependency>

</dependencies>

易于维护、调试。您可以立即更新您的 POM。

我在maven 3.5.4中的解决方案,使用nexus,在eclipse中:

<dependency>
    <groupId>yilin.sheng</groupId>
    <artifactId>webspherecore</artifactId>
    <version>LATEST</version> 
</dependency>

然后在日食中: atl + F5, ,并选择 force update of snapshots/release

这个对我有用。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top