maven依赖冲突以及解决方法

2023-11-15

什么是依赖冲突

依赖冲突是指项目依赖的某一个jar包,有多个不同的版本,因而造成类包版本冲突

依赖冲突的原因

依赖冲突很经常是类包之间的间接依赖引起的。每个显式声明的类包都会依赖于一些其它的隐式类包,这些隐式的类包会被maven间接引入进来,从而造成类包冲突

如何解决依赖冲突

首先查看产生依赖冲突的类jar,其次找出我们不想要的依赖类jar,手工将其排除在外就可以了。具体执行步骤如下

1、查看依赖冲突

a、通过dependency:tree是命令来检查版本冲突

mvn -Dverbose dependency:tree

当敲入上述命令时,控制台会出现形如下内容

[INFO] org.example:hello:jar:1.0-SNAPSHOT
[INFO] +- org.springframework:spring-context:jar:5.2.7.RELEASE:compile
[INFO] |  +- (org.springframework:spring-aop:jar:5.2.7.RELEASE:compile - omitted for conflict with 5.2.0.RELEASE)
[INFO] |  +- org.springframework:spring-beans:jar:5.2.7.RELEASE:compile
[INFO] |  |  \- (org.springframework:spring-core:jar:5.2.7.RELEASE:compile - omitted for duplicate)
[INFO] |  +- org.springframework:spring-core:jar:5.2.7.RELEASE:compile
[INFO] |  |  \- org.springframework:spring-jcl:jar:5.2.7.RELEASE:compile
[INFO] |  \- org.springframework:spring-expression:jar:5.2.7.RELEASE:compile
[INFO] |     \- (org.springframework:spring-core:jar:5.2.7.RELEASE:compile - omitted for duplicate)
[INFO] \- org.springframework:spring-aop:jar:5.2.0.RELEASE:compile
[INFO]    +- (org.springframework:spring-beans:jar:5.2.0.RELEASE:compile - omitted for conflict with 5.2.7.RELEASE)
[INFO]    \- (org.springframework:spring-core:jar:5.2.0.RELEASE:compile - omitted for conflict with 5.2.7.RELEASE)

其中omitted for duplicate表示有jar包被重复依赖,最后写着omitted for conflict with xxx的,说明和别的jar包版本冲突了,而该行的jar包不会被引入。比如上面有一行最后写着omitted for conflict with 5.2.7.RELEASE,表示spring-core 5.2.0版本不会被项目引用,而spring-core 5.2.7版本会被项目引用

b、如果是idea,可以安装maven helper插件来检查依赖冲突

maven helper插件安装成功,点开pom.xml会发现多了一个Dependency Analyzer视图,如下
Dependency Analyzer.png
上面按钮的图标含义如下

  • Conflicts(查看冲突)
  • All Dependencies as List(列表形式查看所有依赖)
  • All Dependencies as Tree(树形式查看所有依赖)

上图说明有3个jar存在冲突,点击冲突的jar,可以查看和哪个jar产生冲突,如下图
查看冲突.png

2、解决冲突

项目的pom.xml形如下

 <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.7.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>5.2.0.RELEASE</version>
        </dependency>


    </dependencies>

通过查看依赖树,我们知道项目会引用5.2.7.RELEASE的spring core jar包,而不会引用5.2.0的jar包,如果我们想用5.2.0版本的spring core包,我们该如何做?

a、使用第一声明者优先原则

谁先定义的就用谁的传递依赖,即在pom.xml文件自上而下,先声明的jar坐标,就先引用该jar的传递依赖。因此我们如果要使用5.2.0版本的spring core包,我们可以改成如下声明

  <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>5.2.0.RELEASE</version>
        </dependency>
        
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.7.RELEASE</version>
        </dependency>

    </dependencies>

查看依赖树

[INFO] org.example:hello:jar:1.0-SNAPSHOT
[INFO] +- org.springframework:spring-aop:jar:5.2.0.RELEASE:compile
[INFO] |  +- org.springframework:spring-beans:jar:5.2.0.RELEASE:compile
[INFO] |  |  \- (org.springframework:spring-core:jar:5.2.0.RELEASE:compile - omitted for duplicate)
[INFO] |  \- org.springframework:spring-core:jar:5.2.0.RELEASE:compile
[INFO] |     \- org.springframework:spring-jcl:jar:5.2.0.RELEASE:compile
[INFO] \- org.springframework:spring-context:jar:5.2.7.RELEASE:compile
[INFO]    +- (org.springframework:spring-aop:jar:5.2.7.RELEASE:compile - omitted for conflict with 5.2.0.RELEASE)
[INFO]    +- (org.springframework:spring-beans:jar:5.2.7.RELEASE:compile - omitted for conflict with 5.2.0.RELEASE)
[INFO]    +- (org.springframework:spring-core:jar:5.2.7.RELEASE:compile - omitted for conflict with 5.2.0.RELEASE)
[INFO]    \- org.springframework:spring-expression:jar:5.2.7.RELEASE:compile
[INFO]       \- (org.springframework:spring-core:jar:5.2.7.RELEASE:compile - omitted for conflict with 5.2.0.RELEASE)

通过依赖树,我们可以看到项目已经引入5.2.0版本的spring core包

b、使用路径近者优先原则

即直接依赖级别高于传递依赖。因此我们可以在最先的pom.xml添加如下内容

 <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.7.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>5.2.0.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>5.2.0.RELEASE</version>
        </dependency>



    </dependencies>

路径近者优先.png通过上图可以看到项目引入是 spring core 5.2.0的包

c、排除依赖

排除依赖如果是idea,可以使用maven helper插件进行排除。点开pom.xml,切换到Dependency Analyzer视图,选择All Dependencies as Tree,点击要排除的jar,右键会出现Execlude选项,如下
去除依赖.png
它产生的效果和如下配置是一样

 <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.7.RELEASE</version>
            <exclusions>
                <exclusion>
                    <artifactId>spring-core</artifactId>
                    <groupId>org.springframework</groupId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>5.2.0.RELEASE</version>
        </dependency>

    </dependencies>

查看依赖.png
通过上图可以看到项目引入是 spring core 5.2.0的包

4、版本锁定

使用dependencyManagement 进行版本锁定,dependencyManagement可以统一管理项目的版本号,确保应用的各个项目的依赖和版本一致。

如果我们项目中只想使用spring core 5.2.0的包,pom.xml可以改为如下

<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-core</artifactId>
                <version>5.2.0.RELEASE</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.7.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>5.2.0.RELEASE</version>
        </dependency>

    </dependencies>

版本锁定.png
通过上图可以看到项目引入是 spring core 5.2.0的包

总结

综上就是maven如何排查依赖冲突以及解决方法,对于排查依赖个人比较推荐使用maven helper插件,至于解决依赖冲突个人推荐使用版本锁定的方法,此外dependencyManagement只是声明依赖,并不自动实现引入,因此子项目需要显示的声明需要用的依赖

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

maven依赖冲突以及解决方法 的相关文章

随机推荐

  • linux 线程和进程的区别与联系::

    进程 承担分配系统资源的基本实体 线程 调度的基本单位 线程是进程里面的执行流 线程在进程的地址空间内运行 linux中没有真正意义上的线程 线程是用进程模拟的 地址空间上 线程没有自己独立的地址空间 共享进程的空间 但是进程包含独立的地址
  • 微信小程序-“授权失败”场景的优雅处理

    微信小程序中提供了相关API 让开发者能获取到微信用户的相关信息 在首次去获取的时候会展示一个用户是否同意授权的对话框 发现有不少线上的小程序都没有处理好用户 拒绝授权 导致的 授权失败 场景 一个观点 私认为 开发微信小程序在用户授权上有
  • 蘑菇街前端面试

    vue与jquery的区别 为什么现在很多人使用vue vue怎样实现双向数据绑定 内部原理 1 jQuery首先要获取到dom对象 然后对dom对象进行进行值的修改等操作 2 Vue是首先把值和js对象进行绑定 然后修改js对象的值 Vu
  • iview Table中switch值无法刷新问题

    table里面的开关在修改状态以后 翻页后状态不在变化 render h params gt return h i switch props size large value params row filterContact on可以传入绑
  • Tkinter 组件详解(七):Entry

    Tkinter 组件详解之Entry Entry 输入框 组件通常用于获取用户的输入文本 何时使用 Entry 组件 Entry 组件仅允许用于输入一行文本 如果用于输入的字符串长度比该组件可显示空间更长 那内容将被滚动 这意味着该字符串将
  • leetcode刷题——多维枚举(一)

    题目一 思路 双指针 bool isSubsequence char s char t int fast 0 int slow 0 while slow
  • JavaWeb之Servlet详解

    文章目录 一 什么是Servlet 二 Servlet 1 Servlet是如何起作用的 2 Servlet接口中的方法 3 Servlet对象的生命周期 三 ServletConfig 1 什么是ServletConfig 2 Servl
  • MOS驱动自举电容和限流电阻的选取

    自举电容选取 最近做逆变时出现了异常 使用2104驱动MOS管 蓝色为滤波后双端带载时出现的波形 一端带载时没有问题 放大波形后发现输出波形在占空比满值时垮掉 产生严重的震荡 可以看到波形顶部斜向下 我们可以推断是驱动自举电容值偏小 当占空
  • ARMv8-A 地址翻译技术之MMU的前世今生

    MMU的重要性不言而喻 支撑操作系统之上的各种复杂应用 但在正式讲MMU之前 我们先说说MMU的发展史 因为ARMv8 A的MMU相当复杂 直接切入正题 会显得比较枯燥 废话不多说 咱们马上开始 一 前言 关于虚拟内存系统的演变史 MMU在
  • 计划 060703

    ESOE项目暂时作为一个自娱型项目 每日投入30分钟 近期按计划完成以下工作 1 完成计划 ok 2 完成对ESOE项目的介绍 ok 060704 3 在blog发布已有的 ESOE Specification v0 1 doc 英文版 o
  • 什么是.NET架构

    什么是 NET架构 NET架构主要分为3部分 FCL Framework Class Library CTS Common Type System 其中包括Common Language Specification CLR Common L
  • 教你自制一款简单的助听器

    助听器实质上是一种低频放大器 可用耳机进行放音 当使用者用上耳机后 可提高老年者的听觉 同时可对青少年的学习和记忆能带来方便 一 工作原理 本电路由话筒 前置低放 功率放大电路和耳机等部分组成 原理电路图见图1 其印刷板电路图见图2 驻极体
  • c++面对对象基础知识

    一 类的定义格式 class calss name private data member declarations public member functions 二 构造函数 1 在程序声明对象时 将自动调用构造函数 2 c 提供两种构
  • 腾讯2017暑期实习生笔试题题解

    7个月没有刷题了 现在真的是菜到爆炸 所以来牛客水一水编程题 一 构造回文 题意 给定一个字符串s 你可以从中删除一些字符 使得剩下的串是一个回文串 如何删除才能使得回文串最长呢 输出需要删除的字符个数 输入描述 输入数据有多组 每组包含一
  • 获取配置文件中的属性

    spring boot的工程启动的时候 内部文件默认是加载classpath路径或者classpath config目录下的application properties文件的 当然也可以指定加载其它的配置文件 如何获取配置文件中的属性呢 实
  • VSCODE如何汉化成中文

    VSCODE默认是以英文显示的 对于不习惯用英文的朋友可以将VSCODE汉化成中文 小编来说下如何汉化吧 工具 原料 VSCODE 方法 步骤 1 VSCODE默认情况下是英文的 点击左侧菜单栏最底下的四方形按钮打开扩展程序界面 在输入框内
  • 微信小程序之Image那些事

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 前言 一 使用场景 二 使用方式 1 动态读取image大小 2 动态设置style 3 动态赋值 总结 前言 小程序中 Image使用频率是非常高的 不同场景下
  • 深度学习移动端在线训练 --- 基于MNN的端侧Finetune实现

    在决定使用MNN实现在线训练之前 也比较了TNN NCNN 发现目前各大端侧推理引擎的训练框架都不成熟 半斤八两的状态 可能都把精力放在推理和op支持上 但是端侧训练的需求真的少么 fine tune在端侧应用难道不是刚需 端侧推理的实现相
  • 爬虫日常-selenium登录12306,绕过验证

    文章目录 前言 代码设计 前言 hello兄弟们 这里是无聊的网友 愉快的周末过去了 欢迎回到学习频道 书接上文 我们说到了再用selenium登录12306时遇到了滑块验证的问题 当前的网站几乎每家都会在登录模块添加一个认证 来规避各种爬
  • maven依赖冲突以及解决方法

    什么是依赖冲突 依赖冲突是指项目依赖的某一个jar包 有多个不同的版本 因而造成类包版本冲突 依赖冲突的原因 依赖冲突很经常是类包之间的间接依赖引起的 每个显式声明的类包都会依赖于一些其它的隐式类包 这些隐式的类包会被maven间接引入进来