欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-07-15 09:48:01
...

最近在项目中使用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 看一下依赖树,传递依赖的包版本都是正确的:
Maven dependencyManagement中的依赖版本会覆盖传递依赖版本

现在在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>

再来看一下依赖树:
Maven 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包时不会包含这个依赖。

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