转载

dependencyManagement导致版本冲突

今天遇到了一个问题:

程序中某处报了ClassNoDefineError。这个类属于jna框架。检查jna的jar,发现确实没有那个类。关键在于这个报错是在一个依赖内部发生的,jna的jar是这个依赖的内部依赖,即当前应用的一个间接依赖。因为使用的jar是一个比较小众的服务,所以第一印象就是这个服务依赖的jna版本错了。进入到服务的pom看了后,发现该服务使用的jna版本是正确的,但是当前应用的jna版本却是错误的。

首先想到的是依赖冲突,使用如下命令检查了当前应用的全部依赖:

mvn dependency:tree

检查后可以确认当前应用的依赖(包括间接依赖)中只有一个jna框架,可以排除依赖冲突的问题。

仔细思索了一会儿,猜测是spring框架的问题。

退到工程最外部的pom文件,找到了 spring-boot-dependencies

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.0.9.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

检查 spring-boot-dependencies 的pom果然看到了jna的版本变量:

<jna.version>4.5.2</jna.version>

这个版本和应用的版本是一致的。随后在 spring-boot-dependencies 的dependencyManagement中找到了jna框架:

<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>${jna.version}</version>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna-platform</artifactId>
<version>${jna.version}</version>
</dependency>

现在问题清晰了。问题出在maven的 dependencyManagement 上。

dependencyManagement的作用主要是依赖版本控制。其影响的范围包括:

  • 其范围内的未直接声明版本的依赖;
  • 其范围内的所有 间接 依赖(不论声明版本与否)。

在这个应用中, spring-boot-dependencies 是应用pom的 dependencyManagement 成员,因此 spring-boot-dependencies 自己的 dependencyManagement 成员也会传递生效。jna框架是应用通过一个依赖的间接依赖,虽然在这个依赖中指明了jna的版本号,但是受到 spring-boot-dependenciesdependencyManagement 的影响,还是使用了一个早期的版本。

解决方式两个:

  1. 将jna框架也添加到 dependencyManagement 中;
  2. 先exclude掉jna间接依赖,再直接添加jna依赖并声明版本号
原文  https://www.zhyea.com/2019/08/21/dependencymanagement-version-conflict.html
正文到此结束
Loading...