为什么Gradle或Maven没有依赖项版本锁定文件?

jra*_*ali 8 java package-managers gradle maven dependency-resolution

在阅读有关NPM,Yarn,Paket,Cargo等软件包管理器的信息时,我最近被引入了依赖版本锁定文件的概念。我的理解是,它是一个文件,其中列出了所有直接和可传递的依赖关系以及它们的确切含义。版本号,因此可以确保以后的版本使用等效的一组依赖关系。这似乎是一个理想的功能,因为许多程序包管理器已经或正在采用该概念。

我的问题是:

  1. 为什么Maven或Gradle不使用锁定文件?或者,如果这样做,我为什么还没有看到呢?

  2. 在包管理器的依赖关系解决方案策略中允许版本范围与仅允许确切版本相比,其优缺点是什么?

Mik*_*dmo 7

1。

Maven 无法实现您的要求。即使您为直接依赖项设置了特定的版本(应该这样做),由于看似无关的更改,您的传递性依赖项也很容易被无意地更改。例如,在新库上添加依赖项可以为您提供现有传递性依赖项的旧版本。

您需要有一个dependencyManagement部分,其中列出了所有直接和可传递的依赖关系。您仍将无法检测是否删除或添加了传递依赖项,例如NPM提供的功能。缺少的问题是所有依赖项都不再位于dependencyManagement部分中。要检测这些更改,您可以使用我编写的类似https://github.com/vandmo/dependency-lock-maven-plugin的内容。使用它还将使所有内容都没有在dependencyManagement部分中变得不那么重要,因为将检测到传递性依赖项中的更改。

我还建议您在构建中使用https://maven.apache.org/enforcer/enforcer-rules/requireUpperBoundDeps.html,因为Maven会选择树中关闭的传递依赖项的版本,而不是您期望的那样,最高版本。

我已经看到许多由于开发人员意外更改传递依赖关系而导致的运行时问题。

TL; DR:您确实需要Maven中的锁定文件之类的文件,但是由于历史上的意识形态原因,该文件不存在。

2。

我不建议使用版本范围,因为它们会使您的构建不可复制。当涉及传递依赖项时,它的行为也不会像您认为的那样。


Tri*_*cek 5

依赖锁定是 Gradle 5.0 达到一定成熟度的一项功能: https ://docs.gradle.org/current/userguide/dependency_locking.html

Gradle 的实现受到 Nebula 插件的启发:https ://github.com/nebula-plugins/gradle-dependency-lock-plugin

当用作更新锁定机制的输入时,版本范围确实可以很好地工作。因此,对于 Gradle,您实际上可以只针对特定的依赖项,这些依赖项将解析您指定的版本范围:

gradle classes --update-locks org.apache.commons:commons-lang3,org.slf4j:slf4j-api
Run Code Online (Sandbox Code Playgroud)

或者,您可以只是说“去更新我的所有部门”:

gradle dependencies --write-locks
Run Code Online (Sandbox Code Playgroud)

如果您正在研究自动化,指定解析策略也值得审查:https://docs.gradle.org/current/userguide/dependency_resolution.html