如何告诉Maven使用最新版本的依赖项?

时间:2008-08-27 16:17:03

标签: java maven dependencies maven-2 maven-metadata

在Maven中,依赖关系通常设置如下:

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

现在,如果您正在使用频繁发布的库,请不断更新&lt; version&gt;标签可能有点烦人。有没有办法告诉Maven始终使用最新的可用版本(来自存储库)?

12 个答案:

答案 0 :(得分:695)

注意:

此答案仅适用于Maven 2!超过6年前提到的LATESTRELEASE变形have been dropped in Maven 3 "for the sake of reproducible builds"。 请参阅此 Maven 3 compliant solution


如果您总是想使用最新版本,Maven有两个关键字,您可以使用它们作为版本范围的替代方案。您应该小心使用这些选项,因为您不再控制正在使用的插件/依赖项。

  

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

有关详细信息,请参阅POM Syntax section of the Maven book。或者在Dependency Version Ranges上查看此文档,其中:

  • 方括号([&amp; ])表示“已关闭”(含)。
  • 括号((&amp; ))表示“开放”(不包括)。

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

如果需要依赖该工件,则可以使用以下选项(当然可以指定其他version ranges,只显示相关的选项):

声明一个确切的版本(将始终解析为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>

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

<version>LATEST</version>

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

<version>RELEASE</version>

请注意,默认情况下,您自己的部署将更新Maven元数据中的“最新”条目,但要更新“发布”条目,您需要激活Maven super POM中的“发布配置文件”。您可以使用“-Prelease-profile”或“-DperformRelease = true”

执行此操作

值得强调的是,任何允许Maven选择依赖版本(LATEST,RELEASE和版本范围)的方法都会让您开放构建时间问题,因为以后的版本可能会有不同的行为(例如依赖插件以前有过)将默认值从true切换为false,结果令人困惑。)

因此,在版本中定义确切版本通常是个好主意。正如Tim's answer所指出的,maven-versions-plugin是用于更新依赖关系版本的便捷工具,尤其是versions:use-latest-versionsversions:use-latest-releases目标。

答案 1 :(得分:349)

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

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

  • 版本:use-latest-versions 在pom中搜索所有版本 这是一个较新的版本和 用最新的替换它们 版本
  • 版本:use-latest-releases 在pom中搜索所有非SNAPSHOT 版本较新 释放并替换它们 最新发布版本。
  • 版本:update-properties 更新a中定义的属性 项目,以便他们对应 最新版本的 特定的依赖关系。这可以 如果有一组依赖项很有用 必须全部锁定到一个版本。

还提供了以下其他目标:

  • 版本:display-dependency-updates 扫描项目的依赖项和 制作一份报告 更新的依赖项 版本可用。
  • 版本:display-plugin-updates 扫描项目的插件和 生成这些插件的报告 有更新的版本。
  • 版本:update-parent 更新项目的父部分 它引用了最新的 可用版本。例如,如果 你使用企业根POM,这个 如果你需要,目标可能会有所帮助 确保您使用的是最新的 企业根POM的版本。
  • 版本:update-child-modules 更新了其中的父节 一个项目的子模块所以 版本匹配的版本 当前的项目。例如,如果你 有一个聚合器pom也是 它的项目的父项 聚合和孩子们 父版本不同步,这个 mojo可以帮助修复版本 儿童模块。 (注意你可能需要 使用-N选项调用Maven 如果你的目标是为了实现这个目标 项目如此糟糕,以至于它 由于版本无法构建 错配)。
  • 版本:lock-snapshots 在pom中搜索所有-SNAPSHOT 版本并将其替换为 当前的时间戳版本 -SNAPSHOT,例如-20090327.172306-4
  • 版本:unlock-snapshots 在pom中搜索所有时间戳 锁定快照版本并替换 他们用-SNAPSHOT。
  • 版本:resolve-ranges 使用版本范围查找依赖项 将范围解析为具体 正在使用的版本。
  • 版本:use-releases 在pom中搜索所有-SNAPSHOT版本 已被释放并取代 他们与相应的发布 版本
  • 版本:use-next-releases 在pom中搜索所有非SNAPSHOT 版本较新 释放并替换它们 下一个版本。
  • 版本:use-next-versions 在pom中搜索所有版本 这是一个较新的版本和 用下一个版本替换它们。
  • 版本:commit 删除pom.xml.versionsBackup文件。形式 内置的“穷人”的一半 SCM”。
  • 版本:还原从中恢复pom.xml文件 pom.xml.versionsBackup文件。形式 内置的“穷人”的一半 SCM”。

以为我会把它包含在以后的任何参考中。

答案 2 :(得分:165)

请查看this page(“依赖版本范围”部分)。您可能想要做的是像

<version>[1.2.3,)</version>

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

答案 3 :(得分:77)

与其他人不同,我认为您可能总是想要最新的版本的原因有很多。特别是如果你正在进行持续部署(我们有时会在一天内完成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>

我使用release插件进行发布,负责-SNAPSHOT并验证-SNAPSHOT的发布版本(这很重要)。

如果您按我的方式执行操作,您将获得所有快照构建的最新版本以及发布版本的最新版本。您的构建也将是可重现的。

<强>更新

我注意到一些评论询问了这个工作流程的一些细节。我会说我们不再使用这种方法,而且maven版本插件的主要原因是错误的,并且通常本质上是有缺陷的。

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

你真的需要maven的一个独立工具来调整版本(所以你不依赖于pom文件来正确运行)。我用低级语言Bash编写了这样一个工具。该脚本将更新版本插件等版本,并将pom检入源代码控制。它的运行速度比mvn版本插件快100倍。不幸的是,它不是以公开使用的方式编写的,但如果人们感兴趣,我可以这样做,并把它放在gist或github中。

回到工作流程,因为有些评论询问我们这是我们做的事情:

  1. 我们在自己的存储库中有20个左右的项目,并拥有自己的jenkins工作
  2. 当我们发布maven版本插件时使用。该工作流程包含在插件的文档中。 maven发布插件很糟糕(而且我很善良)但它确实有效。有一天,我们计划用更优化的方法替换这种方法。
  3. 当其中一个项目被发布时,jenkins然后运行一个特殊的工作,我们将调用更新所有版本的工作(jenkins如何知道它的发布是一种复杂的方式,部分原因是因为maven jenkins发布插件也非常糟糕)。
  4. 更新所有版本的作业了解所有20个项目。它实际上是一个聚合器pom,它特定于依赖顺序的模块部分中的所有项目。 Jenkins运行我们的魔法groovy / bash foo,将所有项目更新到最新版本,然后签入poms(再次按照依赖顺序基于模块部分完成)。
  5. 对于每个项目,如果pom已更改(由于某些依赖项中的版本更改),则会检入它,然后我们立即ping jenkins以运行该项目的相应作业(这是为了保留构建依赖性顺序,否则你是受SCM民意调查员的支配)。
  6. 此时我认为将版本和自动版本作为一般构建的单独工具是一件好事。

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

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

答案 4 :(得分:30)

依赖项语法位于Dependency Version Requirement Specification文档中。这是为了完整性:

  

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

     
      
  • 1.0:&#34; Soft&#34; 1.0的要求(只是推荐,如果它与依赖的所有其他范围匹配)
  •   
  • [1.0]:&#34; Hard&#34;要求1.0
  •   
  • (,1.0]:x&lt; = 1.0
  •   
  • [1.2,1.3]:1.2&lt; = x&lt; = 1.3
  •   
  • [1.0,2.0):1.0&lt; = x&lt; 2.0
  •   
  • [1.5,):x&gt; = 1.5
  •   
  • (,1.0],[1.2,):x <= 1.0或x&gt; = 1.2;多个集合以逗号分隔
  •   
  • (,1.1),(1.1,):这不包括1.1(例如,如果不知道的话   与此图书馆合作)
  •   

在您的情况下,您可以执行<version>[1.2.3,)</version>

之类的操作

答案 5 :(得分:14)

您是否可能依赖于在开发过程中显然会发生很大变化的开发版本?

您可以使用在必要时覆盖的快照版本,而不是增加开发版本的版本,这意味着您不必在每次微小更改时更改版本标记。像1.0-SNAPSHOT ......

之类的东西

但也许你正在努力实现其他目标;)

答案 6 :(得分:6)

当提出这个问题时,maven中的版本范围存在一些问题,但这些问题已在较新版本的maven中得到解决。 本文非常清楚地介绍了版本范围的工作原理和最佳实践,以便更好地了解maven如何理解版本:https://docs.oracle.com/middleware/1212/core/MAVEN/maven_version.htm#MAVEN8855

答案 7 :(得分:6)

谁曾使用过LATEST,请确保您拥有-U,否则将不会提取最新的快照。

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

答案 8 :(得分:4)

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

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

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

答案 9 :(得分:2)

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

一种解决方法是使用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

答案 10 :(得分:1)

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

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

回答Pascal Thivent在问题评论中已经给出的原因

  

我真的不推荐这种做法(也不使用版本范围)   为了建立可重复性。一个突然开始的构建   因未知原因而失败比手动更新更令人讨厌   版本号。

我会推荐这种做法:

<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。

答案 11 :(得分:1)

maven 3.5.4中的MY解决方案,在月食中使用nexus:

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

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

对我有用。