Maven 依赖版本范围
Maven dependency version range
我想了解 [3.8.2] 与 3.8.2 在提到我们的依赖项版本时的区别。
来自 here ,
When declaring a "normal" version such as 3.8.2 for Junit, internally
this is represented as "allow anything, but prefer 3.8.2." This means
that when a conflict is detected, Maven is allowed to use the conflict
algorithms to choose the best version. If you specify [3.8.2], it
means that only 3.8.2 will be used and nothing else. If somewhere else
there is a dependency that specifies [3.8.1], you would get a build
failure telling you of the conflict. We point this out to make you
aware of the option, but use it sparingly and only when really needed.
The preferred way to resolve this is via dependencyManagement.
但我觉得这里有些不对劲。
如果我为我们的依赖项编写 <version>3.8.2</version>
并且我们的 Maven 存储库中不存在该版本工件,那么它不会选择任何其他东西。构建完全失败。
那么,为什么上面他们说 - "allow anything, but prefer 3.8.2."
此外,他们说 - This means that when a conflict is detected,...
。我无法理解这一点。什么可能是 3.8.2 不会出现但 [3.8.2] 会出现的冲突?
整个过程如下:
第一步:Maven为你的项目构建依赖树,包括你的直接依赖,他们的依赖,你的依赖的依赖等等。
第 2 步:现在 Maven 生成所有节点的列表。如果它只遇到一个版本的依赖(比如 3.8.2 或 [3.8.2]),它将只选择那个版本。
第 3 步:如果 Maven 找到多个版本,魔术就开始了。
如果所有版本都是不带括号的版本(如3.8.2),它会选择依赖调解原则中提到的"nearest"版本。
如果您有一些(或全部)版本范围(如 [1.0.0,2.0.0])或固定版本(如 [1.0.0]),那么它首先会找到所有 ranges/concrete 版本的交集(注意这里不考虑没有括号的版本来找到这个交集)。
如果发现此交集为空,则构建失败。如果它不为空,则它通过选择 "nearest" version/concrete version/version 范围进一步进行。
如果根据最近的定义,我们得到一个版本 range/concrete 版本,那么 Maven 会在找到的版本范围的结果交集中选择最新的可用版本。
如果根据最接近的定义,我们得到一个版本(不是具体版本),那么 Maven 检查该版本是否存在于找到的版本范围的结果交集中。如果是,则选择此版本。如果不是,则 Maven 会在版本范围的结果交集中选择最新的可用版本(并且不会使构建失败)。
引用"allow anything, but prefer 3.8.2"充其量只是误导。 Maven 不会尝试弥补存储库中缺少的依赖项,如果在依赖项树中找到多个版本,它只会 "mediates" 个版本。
我想了解 [3.8.2] 与 3.8.2 在提到我们的依赖项版本时的区别。
来自 here ,
When declaring a "normal" version such as 3.8.2 for Junit, internally this is represented as "allow anything, but prefer 3.8.2." This means that when a conflict is detected, Maven is allowed to use the conflict algorithms to choose the best version. If you specify [3.8.2], it means that only 3.8.2 will be used and nothing else. If somewhere else there is a dependency that specifies [3.8.1], you would get a build failure telling you of the conflict. We point this out to make you aware of the option, but use it sparingly and only when really needed. The preferred way to resolve this is via dependencyManagement.
但我觉得这里有些不对劲。
如果我为我们的依赖项编写 <version>3.8.2</version>
并且我们的 Maven 存储库中不存在该版本工件,那么它不会选择任何其他东西。构建完全失败。
那么,为什么上面他们说 - "allow anything, but prefer 3.8.2."
此外,他们说 - This means that when a conflict is detected,...
。我无法理解这一点。什么可能是 3.8.2 不会出现但 [3.8.2] 会出现的冲突?
整个过程如下:
第一步:Maven为你的项目构建依赖树,包括你的直接依赖,他们的依赖,你的依赖的依赖等等。
第 2 步:现在 Maven 生成所有节点的列表。如果它只遇到一个版本的依赖(比如 3.8.2 或 [3.8.2]),它将只选择那个版本。
第 3 步:如果 Maven 找到多个版本,魔术就开始了。
如果所有版本都是不带括号的版本(如3.8.2),它会选择依赖调解原则中提到的"nearest"版本。
如果您有一些(或全部)版本范围(如 [1.0.0,2.0.0])或固定版本(如 [1.0.0]),那么它首先会找到所有 ranges/concrete 版本的交集(注意这里不考虑没有括号的版本来找到这个交集)。
如果发现此交集为空,则构建失败。如果它不为空,则它通过选择 "nearest" version/concrete version/version 范围进一步进行。
如果根据最近的定义,我们得到一个版本 range/concrete 版本,那么 Maven 会在找到的版本范围的结果交集中选择最新的可用版本。
如果根据最接近的定义,我们得到一个版本(不是具体版本),那么 Maven 检查该版本是否存在于找到的版本范围的结果交集中。如果是,则选择此版本。如果不是,则 Maven 会在版本范围的结果交集中选择最新的可用版本(并且不会使构建失败)。
引用"allow anything, but prefer 3.8.2"充其量只是误导。 Maven 不会尝试弥补存储库中缺少的依赖项,如果在依赖项树中找到多个版本,它只会 "mediates" 个版本。