在Maven中,依赖项通常设置如下:
<dependency> <groupId>wonderful-inc</groupId> <artifactId>dream-library</artifactId> <version>1.2.3</version> </dependency>
现在,如果您正在使用频繁发布的库,不断更新<version>标记可能有些烦人 . 有没有办法告诉Maven始终使用最新的可用版本(来自存储库)?
请看this page(第"Dependency Version Ranges"节) . 你可能想做的事情是这样的
<version>[1.2.3,)</version>
这些版本范围在Maven2中实现 .
事实上甚至在3.x它仍然有效,令人惊讶的是项目的构建和部署 . 但是LATEST / RELEASE关键字在m2e和eclipse中引起问题,ALSO项目依赖于通过LATEST / RELEASE部署的依赖关系无法识别版本 .
如果您尝试将版本定义为属性,它也会导致问题,并将其引用到其他位置 .
所以结论是使用versions-maven-plugin如果可以的话 .
谁曾使用LATEST,请确保你有-U否则不会拉最新的快照 .
mvn -U dependency:copy -Dartifact=com.foo:my-foo:LATEST // pull the latest snapshot for my-foo from all repositories
依赖项语法位于Dependency Version Requirement Specification文档中 . 这是为了完整性:
Dependencies的版本元素定义版本要求,用于计算有效的依赖版本 . 版本要求具有以下语法: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> 之类的事情
当提出这个问题时,maven中的版本范围存在一些问题,但这些问题已在新版本的maven中得到解决 . 本文非常清楚地介绍了版本范围的工作原理和最佳实践,以便更好地理解maven如何理解版本:https://docs.oracle.com/middleware/1212/core/MAVEN/maven_version.htm#MAVEN8855
有时你不想使用版本范围,因为它们似乎“慢”来解决你的依赖关系,特别是当有持续交付并且有大量版本时 - 主要是在大量开发期间 .
一种解决方法是使用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
我的解决方案在maven 3.5.4中,在eclipse中使用nexus:
<dependency> <groupId>yilin.sheng</groupId> <artifactId>webspherecore</artifactId> <version>LATEST</version> </dependency>
然后在eclipse: atl + F5 ,并选择 force update of snapshots/release
atl + F5
force update of snapshots/release
这个对我有用 .
与其他人不同,我认为您可能总是想要最新版本的原因有很多 . 特别是如果您正在进行持续部署(我们有时会在一天内完成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的发布版本(这很重要) .
如果您按照我的方式执行操作,您将获得所有快照构建的最新版本以及发布版本的最新版本 . 您的构建也将是可重现的 .
Update
我注意到一些评论询问了这个工作流程的一些细节 . 我会说我们不再使用这种方法了,而且maven版本插件的主要原因是错误的,并且通常存在固有的缺陷 .
这是有缺陷的,因为要运行版本插件来调整版本,所有现有版本都需要存在才能使pom正确运行 . 这是版本插件无法更新到任何东西的最新版本,如果它找不到pom中引用的版本 . 这实际上相当烦人,因为我们经常为磁盘空间原因清理旧版本 .
实际上你需要一个独立的maven工具来调整版本(所以你不依赖于pom文件来正确运行) . 我用低级语言Bash编写了这样一个工具 . 该脚本将更新版本插件等版本,并将pom检入源代码控制 . 它的运行速度比mvn版本插件快100倍 . 不幸的是,它不是以公开使用的方式编写的,但是如果人们感兴趣我可以这样做并将其放在gist或github中 .
回到工作流程,因为一些评论询问这是我们做的:
我们在他们自己的存储库中有20个左右的项目,他们有自己的jenkins工作
当我们发布maven版本插件时使用 . 该工作流程包含在插件's documentation. The maven release plugin sort of sucks (and I' m很好)但它确实有效 . 有一天,我们计划用更优化的方法替换这种方法 .
当其中一个项目被释放时,jenkins然后运行一个特殊的工作,我们将调用更新所有版本的工作(jenkins如何知道它的发布是一个复杂的方式部分因为maven jenkins发布插件也非常糟糕) .
更新所有版本的作业都知道所有20个项目 . 它实际上是一个聚合器pom,它特定于依赖顺序的modules部分中的所有项目 . Jenkins运行我们的魔法groovy / bash foo,将所有项目更新到最新版本,然后签入poms(再次按照依赖顺序基于模块部分完成) .
对于每个项目,如果pom已更改(由于某些依赖项中的版本更改),则会检入它,然后我们立即ping jenkins以运行该项目的相应作业(这是为了保留构建依赖性顺序,否则您将在SCM Poll调度程序的怜悯) .
在这一点上,我认为将版本和自动版本作为一般构建的单独工具是一件好事 .
现在你可能认为maven有点糟糕,因为上面列出的问题,但实际上这对于没有声明易于解析 extendable 语法(又称XML)的声明的构建工具来说相当困难 .
实际上,我们通过命名空间添加自定义XML属性来帮助提示bash / groovy脚本(例如,不要更新此版本) .
您是否可能依赖于在开发过程中明显改变很多的开发版本?
您可以使用在必要时覆盖的快照版本,而不是增加开发版本的版本,这意味着您不必在每次微小更改时更改版本标记 . 像1.0-SNAPSHOT ......
但也许你正在努力实现其他目标;)
NOTE:
这个答案仅适用于Maven 2! 6年前提到的 LATEST 和 RELEASE metaversions have been dropped in Maven 3 "for the sake of reproducible builds" . 请参考 Maven 3 compliant solution .
LATEST
RELEASE
如果您总是想使用最新版本,Maven有两个关键字,您可以使用它们作为版本范围的替代品 . 您应该小心使用这些选项,因为您不再控制正在使用的插件/依赖项 .
当您依赖插件或依赖项时,可以使用LATEST或RELEASE的版本值 . LATEST是指特定工件的最新发布或快照版本,是特定存储库中最近部署的工件 . RELEASE是指存储库中的最后一个非快照版本 . 通常,设计依赖于工件的非特定版本的软件不是最佳实践 . 如果您正在开发软件,则可能需要使用RELEASE或LATEST作为方便,以便在发布新版本的第三方库时不必更新版本号 . 当您发布软件时,应始终确保您的项目取决于特定版本,以减少您的构建或项目受不受您控制的软件版本影响的可能性 . 如果有的话,请谨慎使用LATEST和RELEASE .
有关详细信息,请参阅POM Syntax section of the Maven book . 或者在Dependency Version Ranges上查看此文档,其中:
方括号( [ & ] )表示"closed"(含) .
[
]
括号( ( & ) )表示"open"(不包括) .
(
)
这是一个说明各种选项的示例 . 在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元数据中的"latest"条目,但要更新"release"条目,您需要激活Maven super POM中的"release-profile" . 您可以使用"-Prelease-profile"或"-DperformRelease=true"执行此操作
值得强调的是,任何允许Maven选择依赖版本(LATEST,RELEASE和版本范围)的方法都会让您开放构建时间问题,因为以后的版本可能会有不同的行为(例如,依赖插件之前已经切换了默认值值从真到假,结果令人困惑) .
因此,在版本中定义确切版本通常是个好主意 . 作为Tim's answer指出,maven-versions-plugin是一个用于更新依赖版本的便利工具,尤其是versions:use-latest-versions和versions:use-latest-releases目标 .
现在我知道这个话题已经过时了,但是阅读问题和OP提供的回答似乎Maven Versions Plugin可能实际上是他问题的更好答案:
特别是以下目标可能有用:
versions:use-latest-versions 在pom中搜索所有版本较新的版本,并将其替换为最新版本 .
versions:use-latest-releases 在pom中搜索已发布的所有非SNAPSHOT版本,并将其替换为最新版本 .
versions:update-properties 更新项目中定义的属性,以便它们对应于特定依赖项的最新可用版本 . 如果必须将一组依赖项全部锁定到一个版本,这将非常有用 .
还提供了以下其他目标:
versions:display-dependency-updates 扫描项目的依赖项,并生成具有更新版本的依赖项的报告 .
versions:display-plugin-updates 扫描项目的插件并生成那些具有更新版本的插件的报告 .
versions:update-parent 更新项目的父节,以便它引用最新的可用版本 . 例如,如果您使用公司根POM,如果您需要确保使用最新版本的公司根POM,则此目标会很有用 .
versions:update-child-modules 更新项目子模块的父节,以使版本与当前项目的版本匹配 . 例如,如果您有一个聚合器pom,它也是它聚合的项目的父级,并且子级和父级版本不同步,则此mojo可以帮助修复子模块的版本 . (注意,如果您的项目因为版本不匹配而无法构建,那么您可能需要使用-N选项调用Maven以运行此目标 .
versions:lock-snapshots 在pom中搜索所有-SNAPSHOT版本,并将其替换为该-SNAPSHOT的当前时间戳版本,例如: -20090327.172306-4
versions:unlock-snapshots 在pom中搜索所有时间戳锁定的快照版本,并用-SNAPSHOT替换它们 .
versions:resolve-ranges 使用版本范围查找依赖项,并将范围解析为正在使用的特定版本 .
versions:use-releases 在pom中搜索已发布的所有-SNAPSHOT版本,并将其替换为相应的发行版本 .
versions:use-next-releases 在pom中搜索所有非SNAPSHOT版本,这些版本是较新的版本,并将其替换为下一个版本 .
versions:use-next-versions 在pom中搜索所有版本较新的版本,并将其替换为下一版本 .
versions:commit 删除了pom.xml.versionsBackup文件 . 形成内置"Poor Man's SCM"的一半 .
versions:revert 从pom.xml.versionsBackup文件恢复pom.xml文件 . 形成内置"Poor Man's SCM"的一半 .
我以为我会把它包含在以后的任何参考中 .
如果你想要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 .
12 回答
请看this page(第"Dependency Version Ranges"节) . 你可能想做的事情是这样的
这些版本范围在Maven2中实现 .
事实上甚至在3.x它仍然有效,令人惊讶的是项目的构建和部署 . 但是LATEST / RELEASE关键字在m2e和eclipse中引起问题,ALSO项目依赖于通过LATEST / RELEASE部署的依赖关系无法识别版本 .
如果您尝试将版本定义为属性,它也会导致问题,并将其引用到其他位置 .
所以结论是使用versions-maven-plugin如果可以的话 .
谁曾使用LATEST,请确保你有-U否则不会拉最新的快照 .
依赖项语法位于Dependency Version Requirement Specification文档中 . 这是为了完整性:
在你的情况下,你可以做
<version>[1.2.3,)</version>
之类的事情当提出这个问题时,maven中的版本范围存在一些问题,但这些问题已在新版本的maven中得到解决 . 本文非常清楚地介绍了版本范围的工作原理和最佳实践,以便更好地理解maven如何理解版本:https://docs.oracle.com/middleware/1212/core/MAVEN/maven_version.htm#MAVEN8855
有时你不想使用版本范围,因为它们似乎“慢”来解决你的依赖关系,特别是当有持续交付并且有大量版本时 - 主要是在大量开发期间 .
一种解决方法是使用versions-maven-plugin . 例如,您可以声明一个属性:
并将versions-maven-plugin添加到您的pom文件中:
然后,为了更新依赖关系,您必须执行目标:
如果版本高于1.1.1,它会告诉您:
我的解决方案在maven 3.5.4中,在eclipse中使用nexus:
然后在eclipse:
atl + F5
,并选择force update of snapshots/release
这个对我有用 .
与其他人不同,我认为您可能总是想要最新版本的原因有很多 . 特别是如果您正在进行持续部署(我们有时会在一天内完成5个版本)并且不想进行多模块项目 .
我所做的是让Hudson / Jenkins为每个构建做以下事情:
那就是我使用版本插件和scm插件来更新依赖项,然后将其检入源代码控制 . 是的,我让我的CI执行SCM签入(无论如何,您必须为maven发布插件执行此操作) .
您需要设置版本插件才能更新您想要的内容:
我使用发布插件来执行发布,它负责-SNAPSHOT并验证是否存在-SNAPSHOT的发布版本(这很重要) .
如果您按照我的方式执行操作,您将获得所有快照构建的最新版本以及发布版本的最新版本 . 您的构建也将是可重现的 .
Update
我注意到一些评论询问了这个工作流程的一些细节 . 我会说我们不再使用这种方法了,而且maven版本插件的主要原因是错误的,并且通常存在固有的缺陷 .
这是有缺陷的,因为要运行版本插件来调整版本,所有现有版本都需要存在才能使pom正确运行 . 这是版本插件无法更新到任何东西的最新版本,如果它找不到pom中引用的版本 . 这实际上相当烦人,因为我们经常为磁盘空间原因清理旧版本 .
实际上你需要一个独立的maven工具来调整版本(所以你不依赖于pom文件来正确运行) . 我用低级语言Bash编写了这样一个工具 . 该脚本将更新版本插件等版本,并将pom检入源代码控制 . 它的运行速度比mvn版本插件快100倍 . 不幸的是,它不是以公开使用的方式编写的,但是如果人们感兴趣我可以这样做并将其放在gist或github中 .
回到工作流程,因为一些评论询问这是我们做的:
我们在他们自己的存储库中有20个左右的项目,他们有自己的jenkins工作
当我们发布maven版本插件时使用 . 该工作流程包含在插件's documentation. The maven release plugin sort of sucks (and I' m很好)但它确实有效 . 有一天,我们计划用更优化的方法替换这种方法 .
当其中一个项目被释放时,jenkins然后运行一个特殊的工作,我们将调用更新所有版本的工作(jenkins如何知道它的发布是一个复杂的方式部分因为maven jenkins发布插件也非常糟糕) .
更新所有版本的作业都知道所有20个项目 . 它实际上是一个聚合器pom,它特定于依赖顺序的modules部分中的所有项目 . Jenkins运行我们的魔法groovy / bash foo,将所有项目更新到最新版本,然后签入poms(再次按照依赖顺序基于模块部分完成) .
对于每个项目,如果pom已更改(由于某些依赖项中的版本更改),则会检入它,然后我们立即ping jenkins以运行该项目的相应作业(这是为了保留构建依赖性顺序,否则您将在SCM Poll调度程序的怜悯) .
在这一点上,我认为将版本和自动版本作为一般构建的单独工具是一件好事 .
现在你可能认为maven有点糟糕,因为上面列出的问题,但实际上这对于没有声明易于解析 extendable 语法(又称XML)的声明的构建工具来说相当困难 .
实际上,我们通过命名空间添加自定义XML属性来帮助提示bash / groovy脚本(例如,不要更新此版本) .
您是否可能依赖于在开发过程中明显改变很多的开发版本?
您可以使用在必要时覆盖的快照版本,而不是增加开发版本的版本,这意味着您不必在每次微小更改时更改版本标记 . 像1.0-SNAPSHOT ......
但也许你正在努力实现其他目标;)
NOTE:
这个答案仅适用于Maven 2! 6年前提到的
LATEST
和RELEASE
metaversions have been dropped in Maven 3 "for the sake of reproducible builds" . 请参考 Maven 3 compliant solution .如果您总是想使用最新版本,Maven有两个关键字,您可以使用它们作为版本范围的替代品 . 您应该小心使用这些选项,因为您不再控制正在使用的插件/依赖项 .
有关详细信息,请参阅POM Syntax section of the Maven book . 或者在Dependency Version Ranges上查看此文档,其中:
方括号(
[
&]
)表示"closed"(含) .括号(
(
&)
)表示"open"(不包括) .这是一个说明各种选项的示例 . 在Maven存储库中,com.foo:my-foo具有以下元数据:
如果需要依赖于该工件,则可以使用以下选项(当然可以指定其他version ranges,只显示相关的选项):
声明一个确切的版本(将始终解析为1.0.1):
声明一个显式版本(除非发生冲突,否则将始终解析为1.0.1,当Maven将选择匹配版本时):
声明所有1.x的版本范围(当前将解析为1.1.1):
声明一个开放式版本范围(将解析为2.0.0):
将版本声明为LATEST(将解析为2.0.0)(从maven 3.x中删除)
将版本声明为RELEASE(将解析为1.1.1)(从maven 3.x中删除):
请注意,默认情况下,您自己的部署将更新Maven元数据中的"latest"条目,但要更新"release"条目,您需要激活Maven super POM中的"release-profile" . 您可以使用"-Prelease-profile"或"-DperformRelease=true"执行此操作
值得强调的是,任何允许Maven选择依赖版本(LATEST,RELEASE和版本范围)的方法都会让您开放构建时间问题,因为以后的版本可能会有不同的行为(例如,依赖插件之前已经切换了默认值值从真到假,结果令人困惑) .
因此,在版本中定义确切版本通常是个好主意 . 作为Tim's answer指出,maven-versions-plugin是一个用于更新依赖版本的便利工具,尤其是versions:use-latest-versions和versions:use-latest-releases目标 .
现在我知道这个话题已经过时了,但是阅读问题和OP提供的回答似乎Maven Versions Plugin可能实际上是他问题的更好答案:
特别是以下目标可能有用:
versions:use-latest-versions 在pom中搜索所有版本较新的版本,并将其替换为最新版本 .
versions:use-latest-releases 在pom中搜索已发布的所有非SNAPSHOT版本,并将其替换为最新版本 .
versions:update-properties 更新项目中定义的属性,以便它们对应于特定依赖项的最新可用版本 . 如果必须将一组依赖项全部锁定到一个版本,这将非常有用 .
还提供了以下其他目标:
versions:display-dependency-updates 扫描项目的依赖项,并生成具有更新版本的依赖项的报告 .
versions:display-plugin-updates 扫描项目的插件并生成那些具有更新版本的插件的报告 .
versions:update-parent 更新项目的父节,以便它引用最新的可用版本 . 例如,如果您使用公司根POM,如果您需要确保使用最新版本的公司根POM,则此目标会很有用 .
versions:update-child-modules 更新项目子模块的父节,以使版本与当前项目的版本匹配 . 例如,如果您有一个聚合器pom,它也是它聚合的项目的父级,并且子级和父级版本不同步,则此mojo可以帮助修复子模块的版本 . (注意,如果您的项目因为版本不匹配而无法构建,那么您可能需要使用-N选项调用Maven以运行此目标 .
versions:lock-snapshots 在pom中搜索所有-SNAPSHOT版本,并将其替换为该-SNAPSHOT的当前时间戳版本,例如: -20090327.172306-4
versions:unlock-snapshots 在pom中搜索所有时间戳锁定的快照版本,并用-SNAPSHOT替换它们 .
versions:resolve-ranges 使用版本范围查找依赖项,并将范围解析为正在使用的特定版本 .
versions:use-releases 在pom中搜索已发布的所有-SNAPSHOT版本,并将其替换为相应的发行版本 .
versions:use-next-releases 在pom中搜索所有非SNAPSHOT版本,这些版本是较新的版本,并将其替换为下一个版本 .
versions:use-next-versions 在pom中搜索所有版本较新的版本,并将其替换为下一版本 .
versions:commit 删除了pom.xml.versionsBackup文件 . 形成内置"Poor Man's SCM"的一半 .
versions:revert 从pom.xml.versionsBackup文件恢复pom.xml文件 . 形成内置"Poor Man's SCM"的一半 .
我以为我会把它包含在以后的任何参考中 .
如果你想要Maven应该使用最新版本的依赖项,那么你可以使用Versions Maven Plugin以及如何使用这个插件,Tim已经给出了一个很好的答案,请按照他的answer .
但作为开发人员,我不会推荐这种做法 . 为什么?
回答为什么Pascal Thivent已在问题的评论中给出
我会推荐这种做法:
它易于维护且易于调试 . 您可以立即更新您的POM .