Maven依赖冲突,何解?

本文涉及到以下几个概念须要注意:依赖冲突、依赖调解、依赖传递。html

依赖冲突是什么

原来运行得好好的代码,在引入一个 Jar 包后出现 NoSuchMethodException、NoClassDefFoundError 等错误提示,那么恭喜你,大几率遇到了依赖冲突apache

在认识依赖冲突以前,咱们先来了解一下 Maven 的依赖调解maven

依赖调解

参考 Maven依赖冲突问题原理简析ide

简单的说,若是一个项目中引入了同一个依赖(jar 包)的两个(或多个)不一样版本,Maven 会对这些依赖作调解,以确保最终(运行时)在项目中对于同一个依赖只引入一个版本。ui

依赖调解的两个原则:spa

  1. 路径最近者优先
  2. 第一声明者优先

依赖冲突

如今咱们已经知道了,在一个项目中是可能引入同一个依赖(jar 包)的不一样版本的。 那么,在同一个 jar 包的不一样版本中可能存在一些差别,好比:.net

  1. 类数量变化,表现形式为类的增长/减小
  2. 类结构变化,表现形式为方法/字段的增长/减小
  3. ......

举个例子,咱们项目中引入了两个版本(1.0、2.0)的依赖 A,通过依赖调解后使用了较高的版本(2.0)。若是该依赖在升级的时候没有保持向下的兼容性,删掉了某些方法,而咱们项目中使用 1.0 版本的地方恰好调用了被删掉的这个方法,就会出现 NoSuchMethodException 异常。插件

存在依赖冲突必定意味着异常吗?

不必定。若是通过依赖调解后最终使用的版本可以兼容全部的使用,程序就能够正常运行。命令行

为何会产生依赖冲突

根本缘由是经过直接或者间接依赖,在代码中引入了同一个依赖的不一样版本。code

怎么解决依赖冲突

  1. 若是能确认高版本向下兼容,那么引入一个高版本 jar 包做为项目的直接依赖(利用路径最近者优先原则)
  2. 用 标签排除掉不须要的依赖。

怎样更快地发现依赖冲突?

在 IDE 中使用 Maven Enforcer Plugin 插件。 这个插件有不少规则,咱们最关心的是 Dependency Convergence规则。 用法:

<plugins>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-enforcer-plugin</artifactId>
        <version>1.4.1</version>
        <configuration>
            <rules><dependencyConvergence/></rules>
        </configuration>
    </plugin>
</plugins>
复制代码

参考官网介绍,该插件有两个执行目标:

  1. enforcer:enforce 用于规则检查
  2. enforcer:display-info 用于显示基本环境信息

执行方式:

  1. 命令行执行 mvn enforcer:enforce
  2. 将该目标绑定到 Maven 的生命周期上自动执行

执行结果:

Dependency convergence error for log4j:log4j:1.2.17 paths to dependency are:
+-com.ricston.conflict:conflict-info:2.1.3-SNAPSHOT
  +-org.slf4j:slf4j-log4j12:1.7.6
    +-log4j:log4j:1.2.17
and
+-com.ricston.conflict:conflict-info:2.1.3-SNAPSHOT
  +-log4j:log4j:1.2.16
复制代码

根据这种方式发现依赖冲突后,咱们就可使用上面提到的两种方式(排除或者引入可用的直接依赖)来解决冲突。

参考

相关文章
相关标签/搜索