Maven dependencyManagement中的依赖版本会覆盖传递依赖版本

最近在项目中使用Maven遇到一个问题,明明传递依赖进来的是最新版本,但引用的还是旧版本。原来在parent pom中的dependencyManagement里指定了一个低版本的依赖,然后传递依赖的包版本就是低版本了。

在Maven官方文档中Introduction to the Dependency Mechanism有一段话:

Dependency management - this allows project authors to 
directly specify the versions of artifacts to be used 
when they are encountered in transitive dependencies or
 in dependencies where no version has been specified.

大概意思是:
pom文件中没有指定版本的依赖或是传递的依赖,如果在dependencyManagement中有指定此依赖版本,那就使用dependencyManagement中定义的版本号。

来一个例子看一下:
假设我pom中的依赖长这样:

<dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>5.0.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.0.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>5.0.1.RELEASE</version>
        </dependency>
    </dependencies>

通过mvn dependency:tree 看一下依赖树,传递依赖的包版本都是正确的:
这里写图片描述

现在在parent中的dependencyManagement加入:

<dependencyManagement>
        <dependencies>
            <dependency>
                <!-- Import dependency management from Spring Boot -->
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>1.5.13.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
</dependencyManagement>

再来看一下依赖树:
这里写图片描述
parent的dependencyManagement中spring boot 依赖的spring版本是4.3.17.RELEASE,将5.0.1.RELEASE的传递依赖进来的spring版本都指定成了4.3.17.RELEASE

包依赖版本不一致,在运行项目时就会有问题了,由此 dependencyManagement 是一个控制依赖包版本的利器,但也会带来一些问题,在排查jar包冲突的时候尤其要注意。

还有一个要注意的是在parent里定义的依赖scope会影响到传递进来的依赖:

<dependencyManagement>
        <dependencies>
           <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
                <version>3.1.0</version>
                <scope>provided</scope>
            </dependency>
        </dependencies>
</dependencyManagement>

继承这个parent的pom里直接依赖或传递依赖servlet-api,scope将是provided,然后你用 jetty 作为一个嵌入式容器启动的时候,会报找不到 servlet-api类的异常。provided 的语义是保证项目正常编译,但在运行项目main方法或打包成一个jar包时不会包含这个依赖。

如何解决

如果传递依赖的版本被 parent 中的 dependencyManagement 版本给覆盖了,那就直接在项目的最上层模块中把这个依赖引进来并指定版本。比如下面这个Spring Boot项目:
在这里插入图片描述
直接在红框里的 pom 文件引入对应的传递依赖,这个模块是 Spring Boot 运行 main 方法的模块,maven 在打包的时候,这个模块里直接引入的依赖优先级都是最高的,其它项目也类似。

参考Maven 父pom中dependencyManagement版本优先级高于传递依赖版本
maven的传递依赖与scope关系

  • 13
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值