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

时间:2022-03-28 20:23:47

In Maven, dependencies are usually set up like this:

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

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

Now, if you are working with libraries that have frequent releases, constantly updating the <version> tag can be somewhat annoying. Is there any way to tell Maven to always use the latest available version (from the repository)?

现在,如果您正在使用频繁发布的库,那么不断更新 <版本> 标记可能会有些烦人。有什么方法可以让Maven始终使用最新的可用版本(来自存储库)吗?

11 个解决方案

#1


629  

NOTE:

注意:

This answer applies to Maven 2 only! The mentioned LATEST and RELEASE metaversions have been dropped in Maven 3 "for the sake of reproducible builds", over 6 years ago. Please refer to this Maven 3 compliant solution.

这个答案只适用于Maven 2 !在6年前的Maven 3中,提到的最新版本和发布的元版本已经被删除了,“为了重现构建”。请参考这个Maven 3兼容的解决方案。


If you always want to use the newest version, Maven has two keywords you can use as an alternative to version ranges. You should use these options with care as you are no longer in control of the plugins/dependencies you are using.

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

When you depend on a plugin or a dependency, you can use the a version value of LATEST or RELEASE. LATEST refers to the latest released or snapshot version of a particular artifact, the most recently deployed artifact in a particular repository. RELEASE refers to the last non-snapshot release in the repository. In general, it is not a best practice to design software which depends on a non-specific version of an artifact. If you are developing software, you might want to use RELEASE or LATEST as a convenience so that you don't have to update version numbers when a new release of a third-party library is released. When you release software, you should always make sure that your project depends on specific versions to reduce the chances of your build or your project being affected by a software release not under your control. Use LATEST and RELEASE with caution, if at all.

当您依赖于插件或依赖项时,您可以使用最新版本或发行版的版本值。最新指的是最近发布或快照版本的特定工件,最近部署的工件在特定的存储库中。RELEASE指的是存储库中的最后一个非快照版本。通常,设计依赖于工件的非特定版本的软件并不是最佳实践。如果您正在开发软件,您可能希望使用发布或最新的作为方便,这样您就不必在发布第三方库的新版本时更新版本号。当您发布软件时,您应该始终确保您的项目依赖于特定的版本,以减少您的构建或项目受到不受您控制的软件发布的影响。如果有的话,使用最新的和发布的警告。

See the POM Syntax section of the Maven book for more details. Or see this doc on Dependency Version Ranges, where:

有关更多细节,请参见Maven book的POM语法部分。或者查看依赖版本范围的doc,其中:

  • A square bracket ( [ & ] ) means "closed" (inclusive).
  • 方括号([&])表示“关闭”(包含)。
  • A parenthesis ( ( & ) ) means "open" (exclusive).
  • 括号((&))表示“打开”(独占)。

Here's an example illustrating the various options. In the Maven repository, com.foo:my-foo has the following metadata:

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

If a dependency on that artifact is required, you have the following options (other version ranges can be specified of course, just showing the relevant ones here):

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

Declare an exact version (will always resolve to 1.0.1):

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

<version>[1.0.1]</version>

Declare an explicit version (will always resolve to 1.0.1 unless a collision occurs, when Maven will select a matching version):

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

<version>1.0.1</version>

Declare a version range for all 1.x (will currently resolve to 1.1.1):

为所有1声明一个版本范围。x(目前将解析为1.1.1):

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

Declare an open-ended version range (will resolve to 2.0.0):

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

<version>[1.0.0,)</version>

Declare the version as LATEST (will resolve to 2.0.0) (removed from maven 3.x)

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

<version>LATEST</version>

Declare the version as RELEASE (will resolve to 1.1.1) (removed from maven 3.x):

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

<version>RELEASE</version>

Note that by default your own deployments will update the "latest" entry in the Maven metadata, but to update the "release" entry, you need to activate the "release-profile" from the Maven super POM. You can do this with either "-Prelease-profile" or "-DperformRelease=true"

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


It's worth emphasising that any approach that allows Maven to pick the dependency versions (LATEST, RELEASE, and version ranges) can leave you open to build time issues, as later versions can have different behaviour (for example the dependency plugin has previously switched a default value from true to false, with confusing results).

值得强调的是,任何方法,允许Maven选择依赖版本(最新版本,和版本范围)可以让你打开构建时间问题,为后来的版本可以具有不同的行为(例如依赖插件之前切换默认值从真,假,令人困惑的结果)。

It is therefore generally a good idea to define exact versions in releases. As Tim's answer points out, the maven-versions-plugin is a handy tool for updating dependency versions, particularly the versions:use-latest-versions and versions:use-latest-releases goals.

因此,在发行版中定义准确的版本通常是一个好主意。正如Tim的回答所指出的,maven-versions-plugin是一个方便的工具,可以用来更新依赖性版本,特别是版本:使用最新版本和版本:use-latest-release目标。

#2


303  

Now I know this topic is old, but reading the question and the OP supplied answer it seems the Maven Versions Plugin might have actually been a better answer to his question:

现在我知道这个主题已经过时了,但是阅读问题和OP提供的答案似乎是Maven版本的插件可能是对他的问题的一个更好的答案:

In particular the following goals could be of use:

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

  • versions:use-latest-versions searches the pom for all versions which have been a newer version and replaces them with the latest version.
  • 版本:使用最新版本在pom上搜索所有版本,并将其替换为最新版本。
  • versions:use-latest-releases searches the pom for all non-SNAPSHOT versions which have been a newer release and replaces them with the latest release version.
  • 版本:use-latest-release在pom中搜索所有非快照版本,这是一个较新的版本,并将其替换为最新版本。
  • versions:update-properties updates properties defined in a project so that they correspond to the latest available version of specific dependencies. This can be useful if a suite of dependencies must all be locked to one version.
  • 版本:更新属性更新项目中定义的属性,以便它们对应于特定依赖项的最新可用版本。如果所有依赖项都必须锁定到一个版本,那么这将非常有用。

The following other goals are also provided:

还提供了下列其他目标:

  • versions:display-dependency-updates scans a project's dependencies and produces a report of those dependencies which have newer versions available.
  • 版本:显示依赖的更新扫描一个项目的依赖关系,并生成一个报告,这些依赖项有较新的版本可用。
  • versions:display-plugin-updates scans a project's plugins and produces a report of those plugins which have newer versions available.
  • 版本:显示插件更新扫描了一个项目的插件,并生成了一个有更新版本的插件的报告。
  • versions:update-parent updates the parent section of a project so that it references the newest available version. For example, if you use a corporate root POM, this goal can be helpful if you need to ensure you are using the latest version of the corporate root POM.
  • 版本:update-parent更新项目的父部分,以便它引用最新的可用版本。例如,如果您使用的是企业root POM,那么如果您需要确保使用的是公司root POM的最新版本,那么这个目标会很有帮助。
  • versions:update-child-modules updates the parent section of the child modules of a project so the version matches the version of the current project. For example, if you have an aggregator pom that is also the parent for the projects that it aggregates and the children and parent versions get out of sync, this mojo can help fix the versions of the child modules. (Note you may need to invoke Maven with the -N option in order to run this goal if your project is broken so badly that it cannot build because of the version mis-match).
  • 版本:更新子模块更新项目子模块的父部分,因此版本与当前项目的版本相匹配。例如,如果您有一个聚合器pom,也就是它聚合的项目的父节点,并且子和父版本不同步,这个mojo可以帮助修复子模块的版本。(注意您可能需要使用-N选项来调用Maven,如果您的项目被破坏得如此严重,以至于无法构建,因为版本错误匹配)。
  • versions:lock-snapshots searches the pom for all -SNAPSHOT versions and replaces them with the current timestamp version of that -SNAPSHOT, e.g. -20090327.172306-4
  • 版本:锁定快照在pom中搜索所有的快照版本,并用该快照的当前时间戳版本替换它们,例如-20090327.172306-4。
  • versions:unlock-snapshots searches the pom for all timestamp locked snapshot versions and replaces them with -SNAPSHOT.
  • 版本:解锁快照在pom中搜索所有时间戳锁定的快照版本,并用-快照替换它们。
  • versions:resolve-ranges finds dependencies using version ranges and resolves the range to the specific version being used.
  • 版本:解析范围使用版本范围发现依赖关系,并解决使用的特定版本的范围。
  • versions:use-releases searches the pom for all -SNAPSHOT versions which have been released and replaces them with the corresponding release version.
  • 版本:use-release在pom中搜索所有已发布的快照版本,并使用相应的发布版本替换它们。
  • versions:use-next-releases searches the pom for all non-SNAPSHOT versions which have been a newer release and replaces them with the next release version.
  • 版本:use-next-release在pom中搜索所有非快照版本,这是一个较新的版本,并将其替换为下一个版本。
  • versions:use-next-versions searches the pom for all versions which have been a newer version and replaces them with the next version.
  • 版本:使用下一个版本搜索所有版本的pom,并将其替换为下一个版本。
  • versions:commit removes the pom.xml.versionsBackup files. Forms one half of the built-in "Poor Man's SCM".
  • 版本:提交删除pom.xml。versionsBackup文件。形成了“穷人的SCM”的一半。
  • versions:revert restores the pom.xml files from the pom.xml.versionsBackup files. Forms one half of the built-in "Poor Man's SCM".
  • 版本:恢复恢复砰的一声。xml文件。versionsBackup文件。形成了“穷人的SCM”的一半。

Just thought I'd include it for any future reference.

我想把它包括在以后的参考资料里。

#3


161  

Please take a look at this page (section "Dependency Version Ranges"). What you might want to do is something like

请查看此页面(“依赖版本范围”一节)。你可能想做的事情是!

<version>[1.2.3,)</version>

These version ranges are implemented in Maven2.

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

#4


72  

Unlike others I think there are many reasons why you might always want the latest version. Particularly if you are doing continuous deployment (we sometimes have like 5 releases in a day) and don't want to do a multi-module project.

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

What I do is make Hudson/Jenkins do the following for every build:

我所做的是让Hudson/Jenkins为每一个构建做以下的工作:

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

That is I use the versions plugin and scm plugin to update the dependencies and then check it in to source control. Yes I let my CI do SCM checkins (which you have to do anyway for the maven release plugin).

我使用了版本插件和scm插件来更新依赖项,然后将其检查到源代码控制中。是的,我让我的CI做了SCM签到(你必须为maven版本插件做任何事情)。

You'll want to setup the versions plugin to only update what you want:

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

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

I use the release plugin to do the release which takes care of -SNAPSHOT and validates that there is a release version of -SNAPSHOT (which is important).

我使用发布插件来做发布,它负责处理-快照,并确认有一个发布版本的-快照(这很重要)。

If you do what I do you will get the latest version for all snapshot builds and the latest release version for release builds. Your builds will also be reproducible.

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

Update

更新

I noticed some comments asking some specifics of this workflow. I will say we don't use this method anymore and the big reason why is the maven versions plugin is buggy and in general is inherently flawed.

我注意到一些评论询问了这个工作流的一些细节。我要说的是,我们不再使用这种方法了,而为什么maven版本的插件是错误的,而且总体上是有缺陷的。

It is flawed because to run the versions plugin to adjust versions all the existing versions need to exist for the pom to run correctly. That is the versions plugin cannot update to the latest version of anything if it can't find the version referenced in the pom. This is actually rather annoying as we often cleanup old versions for disk space reasons.

这是有缺陷的,因为要运行版本插件来调整版本,所有现有版本都需要存在,以便pom能够正常运行。如果不能找到pom中引用的版本,那么这个版本的插件就不能更新到最新版本的任何东西。这实际上相当烦人,因为我们经常为磁盘空间原因清理旧版本。

Really you need a separate tool from maven to adjust the versions (so you don't depend on the pom file to run correctly). I have written such a tool in the the lowly language that is Bash. The script will update the versions like the version plugin and check the pom back into source control. It also runs like 100x faster than the mvn versions plugin. Unfortunately it isn't written in a manner for public usage but if people are interested I could make it so and put it in a gist or github.

实际上,您需要一个来自maven的独立工具来调整版本(所以您不需要依赖pom文件来正确地运行)。我已经用一种低级的语言编写了这样一个工具,那就是Bash。该脚本将更新版本插件,并检查pom回到源代码控制。它的运行速度也比mvn版本的插件快100倍。不幸的是,它不是以公共场合的方式写的,但是如果人们感兴趣的话,我可以把它写下来,把它放在一个要点或github上。

Going back to workflow as some comments asked about that this is what we do:

回到工作流程,一些评论问到这是我们做的:

  1. We have 20 or so projects in their own repositories with their own jenkins jobs
  2. 我们在他们自己的仓库里有20个项目,他们有自己的jenkins工作。
  3. When we release the maven release plugin is used. The workflow of that is covered in the plugin's documentation. The maven release plugin sort of sucks (and I'm being kind) but it does work. One day we plan on replacing this method with something more optimal.
  4. 当我们发布maven版本插件时。在插件的文档中包含了这个工作流。maven版本插件有点糟糕(我也很好),但它确实有效。有一天我们计划用更理想的方法来代替这个方法。
  5. When one of the projects gets released jenkins then runs a special job we will call the update all versions job (how jenkins knows its a release is a complicated manner in part because the maven jenkins release plugin is pretty crappy as well).
  6. 当其中一个项目被发布时,jenkins会运行一个特殊的工作,我们会调用更新所有版本的工作(jenkins知道它的发布是一种复杂的方式,部分原因是maven jenkins发布的插件也很糟糕)。
  7. The update all versions job knows about all the 20 projects. It is actually an aggregator pom to be specific with all the projects in the modules section in dependency order. Jenkins runs our magic groovy/bash foo that will pull all the projects update the versions to the latest and then checkin the poms (again done in dependency order based on the modules section).
  8. 更新所有版本的作业知道所有的20个项目。它实际上是一个聚合器pom,它是特定于依赖顺序的模块部分中的所有项目的。Jenkins运行我们的神奇的groovy/bash foo,它将把所有的项目更新到最新的版本,然后签入pom(再一次基于模块部分的依赖顺序)。
  9. For each project if the pom has changed (because of a version change in some dependency) it is checked in and then we immediately ping jenkins to run the corresponding job for that project (this is to preserve build dependency order otherwise you are at the mercy of the SCM Poll scheduler).
  10. 为每个项目如果pom改变了(因为一个版本变化在某些依赖)检查,然后我们马上萍詹金斯运行相应的工作项目(这是为了保护构建依赖订单否则你的摆布SCM调查调度器)。

At this point I'm of the opinion it is a good thing to have the release and auto version a separate tool from your general build anyway.

在这一点上,我认为让发布和自动版本从您的通用构建中分离出来是一件好事。

Now you might think maven sort of sucks because of the problems listed above but this actually would be fairly difficult with a build tool that does not have a declarative easy to parse extendable syntax (aka XML).

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

In fact we add custom XML attributes through namespaces to help hint bash/groovy scripts (e.g. don't update this version).

实际上,我们通过名称空间添加定制的XML属性,以帮助提示bash/groovy脚本(例如,不要更新这个版本)。

#5


25  

The dependencies syntax is located at the Dependency Version Requirement Specification documentation. Here it is is for completeness:

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

Dependencies' version element define version requirements, used to compute effective dependency version. Version requirements have the following syntax:

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

  • 1.0: "Soft" requirement on 1.0 (just a recommendation, if it matches all other ranges for the dependency)
  • 1.0:1.0版的“软”需求(仅是推荐,如果它与依赖项的其他范围匹配)
  • [1.0]: "Hard" requirement on 1.0
  • [1.0]:1.0版的“硬”要求。
  • (,1.0]: x <= 1.0
  • (1.0):x < = 1.0
  • [1.2,1.3]: 1.2 <= x <= 1.3
  • [1.2,1.3]:1.2 <= x <= 1.3。
  • [1.0,2.0): 1.0 <= x < 2.0
  • [1.0,2.0]:1.0 <= x < 2.0。
  • [1.5,): x >= 1.5
  • (1.5):x > = 1.5
  • (,1.0],[1.2,): x <= 1.0 or x >= 1.2; multiple sets are comma-separated
  • (1.0),[1.2,]:x <= 1.0或x >= 1.2;用逗号分隔多个集
  • (,1.1),(1.1,): this excludes 1.1 (for example if it is known not to work in combination with this library)
  • (1.1)(1.1):这一项不包括1.1(例如,如果已知不与此库结合使用)

In your case, you could do something like <version>[1.2.3,)</version>

在您的案例中,您可以做一些类似于 <版本> [1.2.3,) 。

#6


14  

Are you possibly depending on development versions that obviously change a lot during development?

您是否可能依赖于在开发过程中明显地改变了很多的开发版本?

Instead of incrementing the version of development releases, you could just use a snapshot version that you overwrite when necessary, which means you wouldn't have to change the version tag on every minor change. Something like 1.0-SNAPSHOT...

您可以使用在必要时覆盖的快照版本,而不是增加开发版本的版本,这意味着您不必在每个微小的更改上更改版本标记。类似1.0快照……

But maybe you are trying to achieve something else ;)

但也许你正在努力实现别的目标;

#7


6  

Who ever is using LATEST, please make sure you have -U otherwise the latest snapshot won't be pulled.

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

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

#8


5  

By the time this question was posed there were some kinks with version ranges in maven, but these have been resolved in newer versions of maven. This article captures very well how version ranges work and best practices to better understand how maven understands versions: https://docs.oracle.com/middleware/1212/core/MAVEN/maven_version.htm#MAVEN8855

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

#9


3  

The truth is even in 3.x it still works, surprisingly the projects builds and deploys. But the LATEST/RELEASE keyword causing problems in m2e and eclipse all over the place, ALSO projects depends on the dependency which deployed through the LATEST/RELEASE fail to recognize the version.

事实甚至是3。它仍然有效,令人惊讶的是项目构建和部署。但是,最新的/发布的关键字导致了m2e和eclipse的所有问题,而且项目依赖于通过最新/发行版部署的依赖项没有识别出版本。

It will also causing problem if you are try to define the version as property, and reference it else where.

如果您试图将版本定义为属性,并在其他地方引用它,那么它也会引起问题。

So the conclusion is use the versions-maven-plugin if you can.

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

#10


2  

Sometimes you don't want to use version ranges, because it seems that they are "slow" to resolve your dependencies, especially when there is continuous delivery in place and there are tons of versions - mainly during heavy development.

有时您不希望使用版本范围,因为它们似乎“缓慢”地解决您的依赖关系,特别是在持续交付的情况下,并且有大量的版本——主要是在繁重的开发过程中。

One workaround would be to use the versions-maven-plugin. For example, you can declare a property:

一个解决方案是使用版本-maven-plugin。例如,您可以声明一个属性:

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

and add the versions-maven-plugin to your pom file:

并将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>

Then, in order to update the dependency, you have to execute the goals:

然后,为了更新依赖项,您必须执行目标:

mvn versions:update-properties validate

If there is a version newer than 1.1.1, it will tell you:

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

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

#11


0  

If you want Maven should use the latest version of a dependency, then you can use Versions Maven Plugin and how to use this plugin, Tim has already given a good answer, follow his answer.

如果您希望Maven使用最新版本的依赖项,那么您可以使用版本Maven插件以及如何使用这个插件,Tim已经给出了一个很好的答案,按照他的回答。

But as a developer, I will not recommend this type of practices. WHY?

但是作为一个开发人员,我不推荐这种类型的实践。为什么?

answer to why is already given by Pascal Thivent in the comment of the question

在这个问题的评论中,Pascal Thivent已经给出了答案。

I really don't recommend this practice (nor using version ranges) for the sake of build reproducibility. A build that starts to suddenly fail for an unknown reason is way more annoying than updating manually a version number.

我真的不推荐这种做法(也不使用版本范围)来构建重现性。由于未知原因而突然失败的构建比手动更新版本号更令人讨厌。

I will recommend this type of practice:

我将推荐这类练习:

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

it is easy to maintain and easy to debug. You can update your POM in no time.

它易于维护,易于调试。你可以随时更新你的POM。

#1


629  

NOTE:

注意:

This answer applies to Maven 2 only! The mentioned LATEST and RELEASE metaversions have been dropped in Maven 3 "for the sake of reproducible builds", over 6 years ago. Please refer to this Maven 3 compliant solution.

这个答案只适用于Maven 2 !在6年前的Maven 3中,提到的最新版本和发布的元版本已经被删除了,“为了重现构建”。请参考这个Maven 3兼容的解决方案。


If you always want to use the newest version, Maven has two keywords you can use as an alternative to version ranges. You should use these options with care as you are no longer in control of the plugins/dependencies you are using.

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

When you depend on a plugin or a dependency, you can use the a version value of LATEST or RELEASE. LATEST refers to the latest released or snapshot version of a particular artifact, the most recently deployed artifact in a particular repository. RELEASE refers to the last non-snapshot release in the repository. In general, it is not a best practice to design software which depends on a non-specific version of an artifact. If you are developing software, you might want to use RELEASE or LATEST as a convenience so that you don't have to update version numbers when a new release of a third-party library is released. When you release software, you should always make sure that your project depends on specific versions to reduce the chances of your build or your project being affected by a software release not under your control. Use LATEST and RELEASE with caution, if at all.

当您依赖于插件或依赖项时,您可以使用最新版本或发行版的版本值。最新指的是最近发布或快照版本的特定工件,最近部署的工件在特定的存储库中。RELEASE指的是存储库中的最后一个非快照版本。通常,设计依赖于工件的非特定版本的软件并不是最佳实践。如果您正在开发软件,您可能希望使用发布或最新的作为方便,这样您就不必在发布第三方库的新版本时更新版本号。当您发布软件时,您应该始终确保您的项目依赖于特定的版本,以减少您的构建或项目受到不受您控制的软件发布的影响。如果有的话,使用最新的和发布的警告。

See the POM Syntax section of the Maven book for more details. Or see this doc on Dependency Version Ranges, where:

有关更多细节,请参见Maven book的POM语法部分。或者查看依赖版本范围的doc,其中:

  • A square bracket ( [ & ] ) means "closed" (inclusive).
  • 方括号([&])表示“关闭”(包含)。
  • A parenthesis ( ( & ) ) means "open" (exclusive).
  • 括号((&))表示“打开”(独占)。

Here's an example illustrating the various options. In the Maven repository, com.foo:my-foo has the following metadata:

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

If a dependency on that artifact is required, you have the following options (other version ranges can be specified of course, just showing the relevant ones here):

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

Declare an exact version (will always resolve to 1.0.1):

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

<version>[1.0.1]</version>

Declare an explicit version (will always resolve to 1.0.1 unless a collision occurs, when Maven will select a matching version):

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

<version>1.0.1</version>

Declare a version range for all 1.x (will currently resolve to 1.1.1):

为所有1声明一个版本范围。x(目前将解析为1.1.1):

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

Declare an open-ended version range (will resolve to 2.0.0):

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

<version>[1.0.0,)</version>

Declare the version as LATEST (will resolve to 2.0.0) (removed from maven 3.x)

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

<version>LATEST</version>

Declare the version as RELEASE (will resolve to 1.1.1) (removed from maven 3.x):

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

<version>RELEASE</version>

Note that by default your own deployments will update the "latest" entry in the Maven metadata, but to update the "release" entry, you need to activate the "release-profile" from the Maven super POM. You can do this with either "-Prelease-profile" or "-DperformRelease=true"

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


It's worth emphasising that any approach that allows Maven to pick the dependency versions (LATEST, RELEASE, and version ranges) can leave you open to build time issues, as later versions can have different behaviour (for example the dependency plugin has previously switched a default value from true to false, with confusing results).

值得强调的是,任何方法,允许Maven选择依赖版本(最新版本,和版本范围)可以让你打开构建时间问题,为后来的版本可以具有不同的行为(例如依赖插件之前切换默认值从真,假,令人困惑的结果)。

It is therefore generally a good idea to define exact versions in releases. As Tim's answer points out, the maven-versions-plugin is a handy tool for updating dependency versions, particularly the versions:use-latest-versions and versions:use-latest-releases goals.

因此,在发行版中定义准确的版本通常是一个好主意。正如Tim的回答所指出的,maven-versions-plugin是一个方便的工具,可以用来更新依赖性版本,特别是版本:使用最新版本和版本:use-latest-release目标。

#2


303  

Now I know this topic is old, but reading the question and the OP supplied answer it seems the Maven Versions Plugin might have actually been a better answer to his question:

现在我知道这个主题已经过时了,但是阅读问题和OP提供的答案似乎是Maven版本的插件可能是对他的问题的一个更好的答案:

In particular the following goals could be of use:

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

  • versions:use-latest-versions searches the pom for all versions which have been a newer version and replaces them with the latest version.
  • 版本:使用最新版本在pom上搜索所有版本,并将其替换为最新版本。
  • versions:use-latest-releases searches the pom for all non-SNAPSHOT versions which have been a newer release and replaces them with the latest release version.
  • 版本:use-latest-release在pom中搜索所有非快照版本,这是一个较新的版本,并将其替换为最新版本。
  • versions:update-properties updates properties defined in a project so that they correspond to the latest available version of specific dependencies. This can be useful if a suite of dependencies must all be locked to one version.
  • 版本:更新属性更新项目中定义的属性,以便它们对应于特定依赖项的最新可用版本。如果所有依赖项都必须锁定到一个版本,那么这将非常有用。

The following other goals are also provided:

还提供了下列其他目标:

  • versions:display-dependency-updates scans a project's dependencies and produces a report of those dependencies which have newer versions available.
  • 版本:显示依赖的更新扫描一个项目的依赖关系,并生成一个报告,这些依赖项有较新的版本可用。
  • versions:display-plugin-updates scans a project's plugins and produces a report of those plugins which have newer versions available.
  • 版本:显示插件更新扫描了一个项目的插件,并生成了一个有更新版本的插件的报告。
  • versions:update-parent updates the parent section of a project so that it references the newest available version. For example, if you use a corporate root POM, this goal can be helpful if you need to ensure you are using the latest version of the corporate root POM.
  • 版本:update-parent更新项目的父部分,以便它引用最新的可用版本。例如,如果您使用的是企业root POM,那么如果您需要确保使用的是公司root POM的最新版本,那么这个目标会很有帮助。
  • versions:update-child-modules updates the parent section of the child modules of a project so the version matches the version of the current project. For example, if you have an aggregator pom that is also the parent for the projects that it aggregates and the children and parent versions get out of sync, this mojo can help fix the versions of the child modules. (Note you may need to invoke Maven with the -N option in order to run this goal if your project is broken so badly that it cannot build because of the version mis-match).
  • 版本:更新子模块更新项目子模块的父部分,因此版本与当前项目的版本相匹配。例如,如果您有一个聚合器pom,也就是它聚合的项目的父节点,并且子和父版本不同步,这个mojo可以帮助修复子模块的版本。(注意您可能需要使用-N选项来调用Maven,如果您的项目被破坏得如此严重,以至于无法构建,因为版本错误匹配)。
  • versions:lock-snapshots searches the pom for all -SNAPSHOT versions and replaces them with the current timestamp version of that -SNAPSHOT, e.g. -20090327.172306-4
  • 版本:锁定快照在pom中搜索所有的快照版本,并用该快照的当前时间戳版本替换它们,例如-20090327.172306-4。
  • versions:unlock-snapshots searches the pom for all timestamp locked snapshot versions and replaces them with -SNAPSHOT.
  • 版本:解锁快照在pom中搜索所有时间戳锁定的快照版本,并用-快照替换它们。
  • versions:resolve-ranges finds dependencies using version ranges and resolves the range to the specific version being used.
  • 版本:解析范围使用版本范围发现依赖关系,并解决使用的特定版本的范围。
  • versions:use-releases searches the pom for all -SNAPSHOT versions which have been released and replaces them with the corresponding release version.
  • 版本:use-release在pom中搜索所有已发布的快照版本,并使用相应的发布版本替换它们。
  • versions:use-next-releases searches the pom for all non-SNAPSHOT versions which have been a newer release and replaces them with the next release version.
  • 版本:use-next-release在pom中搜索所有非快照版本,这是一个较新的版本,并将其替换为下一个版本。
  • versions:use-next-versions searches the pom for all versions which have been a newer version and replaces them with the next version.
  • 版本:使用下一个版本搜索所有版本的pom,并将其替换为下一个版本。
  • versions:commit removes the pom.xml.versionsBackup files. Forms one half of the built-in "Poor Man's SCM".
  • 版本:提交删除pom.xml。versionsBackup文件。形成了“穷人的SCM”的一半。
  • versions:revert restores the pom.xml files from the pom.xml.versionsBackup files. Forms one half of the built-in "Poor Man's SCM".
  • 版本:恢复恢复砰的一声。xml文件。versionsBackup文件。形成了“穷人的SCM”的一半。

Just thought I'd include it for any future reference.

我想把它包括在以后的参考资料里。

#3


161  

Please take a look at this page (section "Dependency Version Ranges"). What you might want to do is something like

请查看此页面(“依赖版本范围”一节)。你可能想做的事情是!

<version>[1.2.3,)</version>

These version ranges are implemented in Maven2.

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

#4


72  

Unlike others I think there are many reasons why you might always want the latest version. Particularly if you are doing continuous deployment (we sometimes have like 5 releases in a day) and don't want to do a multi-module project.

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

What I do is make Hudson/Jenkins do the following for every build:

我所做的是让Hudson/Jenkins为每一个构建做以下的工作:

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

That is I use the versions plugin and scm plugin to update the dependencies and then check it in to source control. Yes I let my CI do SCM checkins (which you have to do anyway for the maven release plugin).

我使用了版本插件和scm插件来更新依赖项,然后将其检查到源代码控制中。是的,我让我的CI做了SCM签到(你必须为maven版本插件做任何事情)。

You'll want to setup the versions plugin to only update what you want:

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

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

I use the release plugin to do the release which takes care of -SNAPSHOT and validates that there is a release version of -SNAPSHOT (which is important).

我使用发布插件来做发布,它负责处理-快照,并确认有一个发布版本的-快照(这很重要)。

If you do what I do you will get the latest version for all snapshot builds and the latest release version for release builds. Your builds will also be reproducible.

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

Update

更新

I noticed some comments asking some specifics of this workflow. I will say we don't use this method anymore and the big reason why is the maven versions plugin is buggy and in general is inherently flawed.

我注意到一些评论询问了这个工作流的一些细节。我要说的是,我们不再使用这种方法了,而为什么maven版本的插件是错误的,而且总体上是有缺陷的。

It is flawed because to run the versions plugin to adjust versions all the existing versions need to exist for the pom to run correctly. That is the versions plugin cannot update to the latest version of anything if it can't find the version referenced in the pom. This is actually rather annoying as we often cleanup old versions for disk space reasons.

这是有缺陷的,因为要运行版本插件来调整版本,所有现有版本都需要存在,以便pom能够正常运行。如果不能找到pom中引用的版本,那么这个版本的插件就不能更新到最新版本的任何东西。这实际上相当烦人,因为我们经常为磁盘空间原因清理旧版本。

Really you need a separate tool from maven to adjust the versions (so you don't depend on the pom file to run correctly). I have written such a tool in the the lowly language that is Bash. The script will update the versions like the version plugin and check the pom back into source control. It also runs like 100x faster than the mvn versions plugin. Unfortunately it isn't written in a manner for public usage but if people are interested I could make it so and put it in a gist or github.

实际上,您需要一个来自maven的独立工具来调整版本(所以您不需要依赖pom文件来正确地运行)。我已经用一种低级的语言编写了这样一个工具,那就是Bash。该脚本将更新版本插件,并检查pom回到源代码控制。它的运行速度也比mvn版本的插件快100倍。不幸的是,它不是以公共场合的方式写的,但是如果人们感兴趣的话,我可以把它写下来,把它放在一个要点或github上。

Going back to workflow as some comments asked about that this is what we do:

回到工作流程,一些评论问到这是我们做的:

  1. We have 20 or so projects in their own repositories with their own jenkins jobs
  2. 我们在他们自己的仓库里有20个项目,他们有自己的jenkins工作。
  3. When we release the maven release plugin is used. The workflow of that is covered in the plugin's documentation. The maven release plugin sort of sucks (and I'm being kind) but it does work. One day we plan on replacing this method with something more optimal.
  4. 当我们发布maven版本插件时。在插件的文档中包含了这个工作流。maven版本插件有点糟糕(我也很好),但它确实有效。有一天我们计划用更理想的方法来代替这个方法。
  5. When one of the projects gets released jenkins then runs a special job we will call the update all versions job (how jenkins knows its a release is a complicated manner in part because the maven jenkins release plugin is pretty crappy as well).
  6. 当其中一个项目被发布时,jenkins会运行一个特殊的工作,我们会调用更新所有版本的工作(jenkins知道它的发布是一种复杂的方式,部分原因是maven jenkins发布的插件也很糟糕)。
  7. The update all versions job knows about all the 20 projects. It is actually an aggregator pom to be specific with all the projects in the modules section in dependency order. Jenkins runs our magic groovy/bash foo that will pull all the projects update the versions to the latest and then checkin the poms (again done in dependency order based on the modules section).
  8. 更新所有版本的作业知道所有的20个项目。它实际上是一个聚合器pom,它是特定于依赖顺序的模块部分中的所有项目的。Jenkins运行我们的神奇的groovy/bash foo,它将把所有的项目更新到最新的版本,然后签入pom(再一次基于模块部分的依赖顺序)。
  9. For each project if the pom has changed (because of a version change in some dependency) it is checked in and then we immediately ping jenkins to run the corresponding job for that project (this is to preserve build dependency order otherwise you are at the mercy of the SCM Poll scheduler).
  10. 为每个项目如果pom改变了(因为一个版本变化在某些依赖)检查,然后我们马上萍詹金斯运行相应的工作项目(这是为了保护构建依赖订单否则你的摆布SCM调查调度器)。

At this point I'm of the opinion it is a good thing to have the release and auto version a separate tool from your general build anyway.

在这一点上,我认为让发布和自动版本从您的通用构建中分离出来是一件好事。

Now you might think maven sort of sucks because of the problems listed above but this actually would be fairly difficult with a build tool that does not have a declarative easy to parse extendable syntax (aka XML).

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

In fact we add custom XML attributes through namespaces to help hint bash/groovy scripts (e.g. don't update this version).

实际上,我们通过名称空间添加定制的XML属性,以帮助提示bash/groovy脚本(例如,不要更新这个版本)。

#5


25  

The dependencies syntax is located at the Dependency Version Requirement Specification documentation. Here it is is for completeness:

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

Dependencies' version element define version requirements, used to compute effective dependency version. Version requirements have the following syntax:

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

  • 1.0: "Soft" requirement on 1.0 (just a recommendation, if it matches all other ranges for the dependency)
  • 1.0:1.0版的“软”需求(仅是推荐,如果它与依赖项的其他范围匹配)
  • [1.0]: "Hard" requirement on 1.0
  • [1.0]:1.0版的“硬”要求。
  • (,1.0]: x <= 1.0
  • (1.0):x < = 1.0
  • [1.2,1.3]: 1.2 <= x <= 1.3
  • [1.2,1.3]:1.2 <= x <= 1.3。
  • [1.0,2.0): 1.0 <= x < 2.0
  • [1.0,2.0]:1.0 <= x < 2.0。
  • [1.5,): x >= 1.5
  • (1.5):x > = 1.5
  • (,1.0],[1.2,): x <= 1.0 or x >= 1.2; multiple sets are comma-separated
  • (1.0),[1.2,]:x <= 1.0或x >= 1.2;用逗号分隔多个集
  • (,1.1),(1.1,): this excludes 1.1 (for example if it is known not to work in combination with this library)
  • (1.1)(1.1):这一项不包括1.1(例如,如果已知不与此库结合使用)

In your case, you could do something like <version>[1.2.3,)</version>

在您的案例中,您可以做一些类似于 <版本> [1.2.3,) 。

#6


14  

Are you possibly depending on development versions that obviously change a lot during development?

您是否可能依赖于在开发过程中明显地改变了很多的开发版本?

Instead of incrementing the version of development releases, you could just use a snapshot version that you overwrite when necessary, which means you wouldn't have to change the version tag on every minor change. Something like 1.0-SNAPSHOT...

您可以使用在必要时覆盖的快照版本,而不是增加开发版本的版本,这意味着您不必在每个微小的更改上更改版本标记。类似1.0快照……

But maybe you are trying to achieve something else ;)

但也许你正在努力实现别的目标;

#7


6  

Who ever is using LATEST, please make sure you have -U otherwise the latest snapshot won't be pulled.

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

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

#8


5  

By the time this question was posed there were some kinks with version ranges in maven, but these have been resolved in newer versions of maven. This article captures very well how version ranges work and best practices to better understand how maven understands versions: https://docs.oracle.com/middleware/1212/core/MAVEN/maven_version.htm#MAVEN8855

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

#9


3  

The truth is even in 3.x it still works, surprisingly the projects builds and deploys. But the LATEST/RELEASE keyword causing problems in m2e and eclipse all over the place, ALSO projects depends on the dependency which deployed through the LATEST/RELEASE fail to recognize the version.

事实甚至是3。它仍然有效,令人惊讶的是项目构建和部署。但是,最新的/发布的关键字导致了m2e和eclipse的所有问题,而且项目依赖于通过最新/发行版部署的依赖项没有识别出版本。

It will also causing problem if you are try to define the version as property, and reference it else where.

如果您试图将版本定义为属性,并在其他地方引用它,那么它也会引起问题。

So the conclusion is use the versions-maven-plugin if you can.

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

#10


2  

Sometimes you don't want to use version ranges, because it seems that they are "slow" to resolve your dependencies, especially when there is continuous delivery in place and there are tons of versions - mainly during heavy development.

有时您不希望使用版本范围,因为它们似乎“缓慢”地解决您的依赖关系,特别是在持续交付的情况下,并且有大量的版本——主要是在繁重的开发过程中。

One workaround would be to use the versions-maven-plugin. For example, you can declare a property:

一个解决方案是使用版本-maven-plugin。例如,您可以声明一个属性:

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

and add the versions-maven-plugin to your pom file:

并将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>

Then, in order to update the dependency, you have to execute the goals:

然后,为了更新依赖项,您必须执行目标:

mvn versions:update-properties validate

If there is a version newer than 1.1.1, it will tell you:

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

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

#11


0  

If you want Maven should use the latest version of a dependency, then you can use Versions Maven Plugin and how to use this plugin, Tim has already given a good answer, follow his answer.

如果您希望Maven使用最新版本的依赖项,那么您可以使用版本Maven插件以及如何使用这个插件,Tim已经给出了一个很好的答案,按照他的回答。

But as a developer, I will not recommend this type of practices. WHY?

但是作为一个开发人员,我不推荐这种类型的实践。为什么?

answer to why is already given by Pascal Thivent in the comment of the question

在这个问题的评论中,Pascal Thivent已经给出了答案。

I really don't recommend this practice (nor using version ranges) for the sake of build reproducibility. A build that starts to suddenly fail for an unknown reason is way more annoying than updating manually a version number.

我真的不推荐这种做法(也不使用版本范围)来构建重现性。由于未知原因而突然失败的构建比手动更新版本号更令人讨厌。

I will recommend this type of practice:

我将推荐这类练习:

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

it is easy to maintain and easy to debug. You can update your POM in no time.

它易于维护,易于调试。你可以随时更新你的POM。