Maven 依赖排查

admin2024-05-15  1

先从项目去看显而易见,假如我们有一个项目,父工程中包含一些子工程,如下:

Maven 依赖排查,第1张

我们想看一下samples-account中的依赖关系,那么我们可以打开 samples-account的pom文件,查看其maven依赖关系图。

Maven 依赖排查,第2张

我们可以看到此项目中maven的依赖关系如下。

Maven 依赖排查,第3张

 我们可以看到有很多红色的虚线和红色的实线,对于红色实线来说表示的是maven依赖冲突,对于红色虚线来说表示的是重复依赖或者是依赖被覆盖。

因为很乱,我们可以先按如下操作找到哪些有问题的依赖关系。

Maven 依赖排查,第4张

然后再找到我们要关注的依赖进行分析,如我们要看spring-context-support相关的依赖是否有冲突。我们可以左键单击选中这个节点,然后点击如下按钮:

Maven 依赖排查,第5张

 会自动关注到此依赖,如下图:

Maven 依赖排查,第6张

这样我们可以看到 spring-context-support 有俩版本,且samples-account直接引用过其1.0.5版本,dubbo-config-spring也引用过其1.0.5,dubbo则引用的是他的1.0.11版本(在这里由于就近原则,它的版本被改为1.0.5版本了)。我们从maven树中也能看到:

Maven 依赖排查,第7张

 那么jar包后面的omitted for conflict with 1.0.5是什么意思呢?

而omitted for duplicate又是什么意思呢?

 omitted for conflict with 和 omitted for duplicate有什么区别呢?

对于这些冲突我们怎么解决呢?

假设你的项目(我们称之为project-A)依赖于两个库:library-Xlibrary-Y

  1. library-X 的版本1.0是你的项目直接依赖的。
  2. library-Y 是你的项目直接依赖的另一个库,但它又间接地依赖于library-X的版本2.0(作为它的传递性依赖)。

在Maven的依赖管理中,这会导致一个冲突,因为你的项目试图同时使用library-X的两个不同版本:1.0(直接依赖)和2.0(通过library-Y的传递性依赖)。

Maven的依赖树可能看起来像这样

project-A  
|-- library-X:1.0 (直接依赖)  
|-- library-Y:some-version  
    |-- library-X:2.0 (传递性依赖)

在这个例子中,Maven会尝试解决这个冲突。默认情况下,Maven会选择路径最短的依赖版本,也就是说,它会尽可能地使用直接声明的依赖版本。但是,这并不总是可行的,特别是当两个版本在API或行为上有不兼容的更改的时候。

当然还有项目依赖是这样冲突的:

1.projectA依赖LibraryB,LibraryB又依赖LibraryX1.0。

2.projectA依赖LibraryC,LibraryC又依赖LibraryX2.0。

ProjectA
|-- LibraryB
	|-- LibraryX1.0
|-- LibraryC
	|-- LibraryX2.0

要解决上述Maven依赖冲突问题,你可以通过在项目的pom.xml文件中配置<exclusions>标签来排除不需要的依赖版本。以下是一个示例配置,展示了如何排除LibraryB中的LibraryX 1.0版本依赖,以确保ProjectA只使用LibraryX的2.0版本(假设这是你想要保留的版本):

<project>  
    ...  
    <dependencies>  
        <!-- ProjectA依赖于LibraryB -->  
        <dependency>  
            <groupId>com.example</groupId>  
            <artifactId>LibraryB</artifactId>  
            <version>1.0</version>  
            <exclusions>  
                <!-- 排除LibraryB中的LibraryX 1.0版本 -->  
                <exclusion>  
                    <groupId>com.some.othergroup</groupId>  
                    <artifactId>LibraryX</artifactId>  
                </exclusion>  
            </exclusions>  
        </dependency>  
  
        <!-- ProjectA也依赖于LibraryC -->  
        <dependency>  
            <groupId>com.example</groupId>  
            <artifactId>LibraryC</artifactId>  
            <version>x.y.z</version>  
            <!-- 注意:这里不需要排除LibraryX,因为我们要保留的版本就是LibraryC所依赖的版本 -->  
        </dependency>  
  
        <!-- 直接指定LibraryX的2.0版本 -->  
        <dependency>  
            <groupId>com.some.othergroup</groupId>  
            <artifactId>LibraryX</artifactId>  
            <version>2.0</version>  
        </dependency>  
  
        <!-- 其他依赖... -->  
    </dependencies>  
    ...  
</project>

看着好像有那么点道理,然而,在上面的配置中,直接指定LibraryX的2.0版本可能会引发另一个问题:如果LibraryB确实需要LibraryX的1.0版本来正常工作,那么这种硬编码的依赖可能会导致LibraryB无法正常工作。

因此,更好的做法可能是确保LibraryBLibraryC维护者都更新他们的依赖项以使用兼容的版本,或者在项目的dependencyManagement部分统一指定一个兼容的版本(把问题提给项目的维护者吧)。

<project>  
    ...  
    <dependencyManagement>  
        <dependencies>  
            <!-- 统一指定LibraryX的版本为2.0 -->  
            <dependency>  
                <groupId>com.some.othergroup</groupId>  
                <artifactId>LibraryX</artifactId>  
                <version>2.0</version>  
            </dependency>  
            <!-- 其他依赖管理... -->  
        </dependencies>  
    </dependencyManagement>  
  
    <dependencies>  
        <!-- ProjectA依赖于LibraryB,但不需要显式排除LibraryX,因为dependencyManagement已经指定了版本 -->  
        <dependency>  
            <groupId>com.example</groupId>  
            <artifactId>LibraryB</artifactId>  
            <version>1.0</version>  
        </dependency>  
  
        <!-- ProjectA也依赖于LibraryC,同样不需要显式排除 -->  
        <dependency>  
            <groupId>com.example</groupId>  
            <artifactId>LibraryC</artifactId>  
            <version>x.y.z</version>  
        </dependency>  
  
        <!-- 通常情况下,不需要直接指定LibraryX的版本,因为dependencyManagement已经处理了 -->  
  
        <!-- 其他依赖... -->  
    </dependencies>  
    ...  
</project>

 在dependencyManagement部分指定的版本将作为项目的“首选”版本,Maven将尝试解析所有依赖以使用这个版本(除非在dependencies部分明确指定了不同的版本)。

具体依赖可参照这位博主的描述:maven依赖传递(直接、间接依赖)、解决依赖冲突(排除依赖、版本锁定dependencyManagement)_maven 间接依赖-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明原文出处。如若内容造成侵权/违法违规/事实不符,请联系SD编程学习网:675289112@qq.com进行投诉反馈,一经查实,立即删除!