Maven如何解决传递依赖的版本冲突?最接近者胜策略

19

我终于习惯了在我的项目中没有任何未声明或已声明但未使用的依赖项。虽然很难跟踪列在dependency:analyze中的未使用的声明的运行时/测试依赖项...一个人必须在pom.xml中写注释或以其他方式管理它们,以知道它们是用于测试还是运行时。

但是解决版本冲突的方法对我来说仍然不清楚。关于传递依赖。

最近者优先策略是如何工作的?什么时候使用一个版本而不是另一个版本?

  • 如果您使用版本号声明了已使用但未声明的依赖项-它总是胜出

  • 如果没有明确指定依赖项版本,则Maven无法解决可能涉及此依赖项的任何版本冲突(奇怪,但在这里写了)

  • 如果您没有声明未声明的使用依赖项,则它会选择最接近级别的传递性依赖项(最近者优先策略),如果冲突在同一级别上,则它会在版本A和版本B之间进行某种决策...也许是在处理依赖项时首先遇到的那个胜出


如果您想为测试定义一个依赖项,只需通过作用域来提供它,这也适用于运行时。 - khmarbaise
2个回答

2

我认为依赖关系的解析方式与您所描述的完全相同。

我还认为,如果您在<dependency>中使用<scope>子标签,您的生活会更加轻松。

引用自Maven官方网站:

  1. compile: 这是默认范围,如果未指定,则使用此范围。编译依赖项在项目的所有类路径中都可用。此外,这些依赖项会传播到依赖项目。
  2. provided:这与编译类似,但表示您希望JDK或容器在运行时提供依赖项。例如,在为Java企业版构建Web应用程序时,您将设置对Servlet API和相关Java EE API的依赖项以提供作用域,因为Web容器提供这些类。此范围仅在编译和测试类路径上可用,并且不具有传递性。
  3. runtime:此范围表示编译不需要该依赖项,但执行需要。它在运行时和测试类路径中,但不在编译类路径中。
  4. test:此范围表示该依赖项不需要正常使用应用程序,并且仅可用于测试编译和执行阶段。
  5. system:此范围类似于provided,但您必须显式提供包含它的JAR。该工件始终可用,并且不会在存储库中查找。
  6. import:(仅在Maven 2.0.9或更高版本中可用) 此范围仅用于<dependencyManagement>部分中类型为pom的依赖项。它表示应使用该POM的<dependencyManagement>部分中的依赖项替换指定的POM。由于它们被替换,因此作用域为import的依赖项实际上不参与限制依赖项的传递性。

1

这里有一些关于依赖管理的文档链接:

http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html(在“dependency scope”章节中有一个重要的表格)

有一篇德国期刊的好文章描述了解决依赖问题 - 这是文章的BibTex参考资料:http://www.bibsonomy.org/bibtex/2ef10bb1bc1be7806bc3fba53417bbd5f/funthomas424242

在Sonatype书籍中有一个关于依赖插件的章节: http://www.sonatype.com/books/mvnex-book/reference/optimizing-sect-dependency-plugin.html

希望这些对您有所帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接