0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

实际上手体验maven面对冲突Jar包的加载规则

京东云 来源:jf_75140285 作者:jf_75140285 2024-08-08 11:22 次阅读

一、问题背景

相信大家在日常的开发过程中都遇到过Jar包冲突的问题,emm,在最近处理业务需求时我也遇到了不同版本jar包冲突导致项目加载出错的问题。主要是一个完整的项目会不可避免的使用第三方的Jar包来实现功能开发,各种第三方包之间可能会存在依赖关系,不同版本的依赖就会可能导致依赖间的相互冲突,进而导致整个项目加载的失败。

这篇文章主要记录了本次遇到的问题:即maven在面对不同版本的jar包在pom文件中同时声明会存在加载覆盖的问题,于是通过查询网上相关资料对maven包的加载规则介绍,并通过实际场景对其进行分析验证;

二、maven加载原则

1.最短路径原则:面对多级(两级及以上)的不同依赖,会优先选择路径最短的依赖;

2.声明优先原则:面对多级(两级及以上)的同级依赖,先声明的依赖会覆盖后声明的依赖;

3.同级依赖中,后声明的依赖会覆盖先声明的依赖;

三、本地验证maven加载原则

1.最短路径原则:使用最短路径加载的前提是,项目中存在两级以上的不同依赖jar包,此时项目会优先加载路径最短的jar包;

wKgaoma0OdWAa8w0AAB2VXgMWjY711.png

实例验证:分别在common模块和service模块中间接和直接的引入不同版本的elasticsearch-rest-client,观察项目中面对不同路径长度情况下实际加载时所使用的版本情况。

common模块:common模块中引入elasticsearch-rest-high-level-client 依赖包, 而该依赖包它引入了 elasticsearch-rest-client 7.4.2,从而实现在common模块中间接引用该包;

common的pom文件:

    < dependencies >
        < dependency >
            < groupId >org.elasticsearch.client< /groupId >
            < artifactId >elasticsearch-rest-high-level-client< /artifactId >
            < version >7.4.2< /version >
        < /dependency >
    < /dependencies >

service模块:为了验证不同路径长度下maven的包加载顺序我们在service模块中直接引入elasticsearch-rest-client 6.8.13;

service的pom文件:

    < dependencies >
        < dependency >
            < groupId >org.elasticsearch.client< /groupId >
            < artifactId >elasticsearch-rest-client< /artifactId >
            < version >6.8.13< /version >
        < /dependency >
    < /dependencies >

实际加载结果:在IDEA中加载pom文件时,可以在maven管理中看到已经提示jar包冲突;

wKgZoma0OdeAaipNAAW8bQ33M9M375.png

mvn dependency:tree: 我们可以通过mvn dependency :tree命令来查看该项目的依赖树,观察发现实际加载的版本是elasticsearch-rest-client 6.8.13,符合maven中的最短路径优先原则;

wKgZoma0Od2AFGFbAAJd1U1NqLU170.png



2. 声明优先原则:声明优先原则的前提是对于两级以上的同级依赖,先声明的依赖会覆盖后声明的依赖包;

wKgaoma0Od6AVfGcAAB3NKraoWo129.png

实例验证:针对该原则的验证场景构造不再关注模块是否直接或者间接引用不同版本的es,我们在common模块和service模块中都直接引用不同版本的es,然后通过改变两个模块在pom文件中声明的先后顺序来观察项目启动后实际加载的jar包;

common模块:在common模块中直接引入依赖包elasticsearch-rest-client 7.4.2

    < dependencies >
        < dependency >
            < groupId >org.elasticsearch.client< /groupId >
            < artifactId >elasticsearch-rest-client< /artifactId >
            < version >7.4.2< /version >
        < /dependency >
    < /dependencies >

service模块:在service模块中引入依赖包elasticsearch-rest-client 6.8.13

    < dependencies >
        < dependency >
            < groupId >org.elasticsearch.client< /groupId >
            < artifactId >elasticsearch-rest-client< /artifactId >
            < version >6.8.13< /version >
        < /dependency >
    < /dependencies >

实际加载结果:

▪场景1:我们将common模块在pom文件中先引入,然后将在service模块置于common模块后面引入,观察项目实际加载情况;

    < dependencies >
        < dependency >
            < groupId >org.example< /groupId >
            < artifactId >backend_common< /artifactId >
            < version >1.0-SNAPSHOT< /version >
        < /dependency >

        < dependency >
            < groupId >org.example< /groupId >
            < artifactId >backend_service< /artifactId >
            < version >1.0-SNAPSHOT< /version >
        < /dependency >
    < /dependencies >

▪观察加载结果图,发现实际加载的是es-rest-client 7.4.2, 即确实是common模块声明生效,service模块后声明导致其中的es未被加载。符合声明优先原则;

wKgZoma0Od-ADU6WAAMw7NdHJbc182.png

◦场景2:我们将service模块在pom文件中先引入,然后将在common模块置于service模块后面引入,观察项目实际加载情况;;

    < dependencies >
         < dependency >
            < groupId >org.example< /groupId >
            < artifactId >backend_service< /artifactId >
            < version >1.0-SNAPSHOT< /version >
        < /dependency >
        < dependency >
            < groupId >org.example< /groupId >
            < artifactId >backend_common< /artifactId >
            < version >1.0-SNAPSHOT< /version >
        < /dependency >
    < /dependencies >

▪观察项目实际加载结果图,发现实际加载的是es-rest-client 6.8.13, 即确实是模块声明生效,common模块后声明导致其中的es未被加载。发现符合声明优先原则;

wKgaoma0OeGAQ3kUAANB3XZ-BcI040.png

◦声明优先原则场景验证结束

3. 同级依赖中后加载覆盖先加载原则

wKgZoma0OeKAKD6AAABcOAb-VQo519.png

实例验证:为了构造在同级依赖中的加载场景我们在项目中直接引入两个不同es版本的依赖,然后同样通过改变两个es版本在pom中的声明顺序来观察项目实际加载的es版本。

▪场景1:我们首先验证client 7.4.2依赖包在client 6.8.13之前声明的情况;

    < dependencies >
        < dependency >
            < groupId >org.elasticsearch.client< /groupId >
            < artifactId >elasticsearch-rest-client< /artifactId >
            < version >7.4.2< /version >
        < /dependency >

        < dependency >
            < groupId >org.elasticsearch.client< /groupId >
            < artifactId >elasticsearch-rest-client< /artifactId >
            < version >6.8.13< /version >
        < /dependency >
    < /dependencies >

▪观察maven的实际加载结果如下,发现项目中实际加载的es-rest-client 版本是6.8.13,先声明的7.4.2版本并未实际加载到项目中。符合同级依赖中后加载覆盖先加载原则。

wKgaoma0OeOAPsuUAAJzDPHmeVs054.png

▪场景2:然后我们改变声明顺序,将client 6.8.13依赖包在client 7.4.2之前声明;

    < dependencies >
        < dependency >
            < groupId >org.elasticsearch.client< /groupId >
            < artifactId >elasticsearch-rest-client< /artifactId >
            < version >6.8.13< /version >
        < /dependency >

        < dependency >
            < groupId >org.elasticsearch.client< /groupId >
            < artifactId >elasticsearch-rest-client< /artifactId >
            < version >7.4.2< /version >
        < /dependency >
    < /dependencies >

▪观察maven实际加载结果如下,发现项目中实际加载的es-rest-client 版本是7.4.2,先声明的6.8.13版本并未实际加载到项目中。符合同级依赖中后加载覆盖先加载原则。

wKgZoma0OeSAXPFEAAJ3w85KXR0524.png

四、常见异常

Jar发生冲突后在程序启动时常见异常报错,下面四种异常是能够直观表征Jar包加载冲突

◦程序抛出java.lang.ClassNotFoundException异常;

◦程序抛出java.lang.NoSuchMethodError异常;

◦程序抛出java.lang.NoClassDefFoundError异常;

◦程序抛出java.lang.LinkageError异常等;

五、总结

之前只是浅层的了解maven包的加载,没有结合具体的加载原则进行系统的学习验证,正好通过需求开发中遇到依赖冲突相关问题对maven的加载原则进行探究。ok,明白啦!

审核编辑 黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • maven
    +关注

    关注

    0

    文章

    30

    浏览量

    3713
收藏 人收藏

    评论

    相关推荐

    springboot的项目如何既要用jar启动,同时还可以为不同的机房设置不同的配置文件

    作者:京东科技 李意文 1、首先先把配置文件从jar中抽离 示例代码:   org.apache.maven.plugins maven-jar-plugin 3.2.0
    的头像 发表于 10-19 16:48 516次阅读
    springboot的项目如何既要用<b class='flag-5'>jar</b><b class='flag-5'>包</b>启动,同时还可以为不同的机房设置不同的配置文件

    PLC的IP冲突如何解决(NAt物联网解决方案)

    他网络设备之间的通信将受到严重影响,可能出现数据丢、通信延迟甚至通信中断等问题。 制造商在设备出厂中会将设备IP设置为相同,在接入工厂局域网时便可能与网络中已存在的设备IP冲突;同时动态分配IP的方式也有可能导致多个设备分配到相同的IP地
    的头像 发表于 09-06 10:53 624次阅读
    PLC的IP<b class='flag-5'>冲突</b>如何解决(NAt物联网解决方案)

    AWR294x主引导加载程序和辅助引导加载程序

    电子发烧友网站提供《AWR294x主引导加载程序和辅助引导加载程序.pdf》资料免费下载
    发表于 09-06 09:47 0次下载
    AWR294x主引导<b class='flag-5'>加载</b>程序和辅助引导<b class='flag-5'>加载</b>程序

    AD9元器件间距规则如何设置

    其他潜在问题。以下是设置元器件间距规则的步骤: 一、打开规则设置 启动AD9 :首先,打开Altium Designer 9软件,并加载你的PCB设计文件。 访问规则设置 :在菜单栏中
    的头像 发表于 09-02 15:26 3756次阅读

    使用Nexus在本地搭建npm、yum和maven私有仓库

    使用Nexus在本地搭建npm、yum和maven私有仓库 为保证在无互联网的情况下,可正常搭建、构建项目,并自动化部署项目,本系统采用Nexus+Jenkins+Maven+Gitlab开源组件
    的头像 发表于 08-21 14:46 332次阅读
    使用Nexus在本地搭建npm、yum和<b class='flag-5'>maven</b>私有仓库

    IP地址冲突解决方法图示

    你是否在日常使用网络时,有这样的经历:突然就失去网络连接,时断时续,加载缓慢,文件传输突然中断?网络连接并没有完全断开,但网速变得异常缓慢看电视剧卡顿、下载文件简直龟速?那么你可能是IP地址冲突
    的头像 发表于 07-26 11:51 441次阅读

    iptables 工具常用命令规则有哪些

    iptables 是 Linux 上用于配置 IPv4 数据过滤和 NAT 规则的工具。它可以让您控制数据如何在您的 Linux 服务器上进行转发、过滤和修改。下面是一些基本的 iptables
    发表于 06-12 15:42

    ESP32S3设置输出IO的高低电平后,紧接着去读取电平实际上是没有变化的,为什么?

    设置输出IO的高低电平后,紧接着去读取电平实际上是没有变化的,跑的是例程呀,只是加了两个printf,是哪里出问题了呢
    发表于 06-07 06:37

    气密性检测设备测试不出来电池的泄漏?谣言

    在电池技术领域,关于气密性检测设备无法检测出电池泄漏的说法一直在流传。但今天,我们要用科学的力量来终结这个谣言。实际上,现代的气密性检测设备不仅能检测出电池的泄漏,而且其准确性和可靠性都达到
    的头像 发表于 06-01 16:23 303次阅读
    气密性检测设备测试不出来电池<b class='flag-5'>包</b>的泄漏?谣言

    库克称中国内地iPhone业务实际上实现增长

    苹果公司首席执行官蒂姆·库克(Tim Cook)近日表示,尽管大中华区截至3月份财季的整体收入有所下滑,但中国内地市场的iPhone业务实际上实现了增长,且降幅低于预期。这一积极信号显示了中国市场对于苹果产品的强劲需求。
    的头像 发表于 05-09 09:40 322次阅读

    电芯压力加载试验机:新能源动力电池安全的守护者-精诚工科

    JCGK精诚工科电芯压力加载试验机是检测电芯安全性的专用设备,通过模拟实际使用中的压力情况,评估电芯的结构稳定性和安全性。该设备广泛应用于电池制造业、新能源汽车、消费电子等领域,确保电池在各种条件下都能安全稳定地工作。
    的头像 发表于 04-26 17:59 663次阅读
    电芯压力<b class='flag-5'>加载</b>试验机:新能源动力电池<b class='flag-5'>包</b>安全的守护者-精诚工科

    Ubuntu系统快速上手

    Ubuntu系统快速上手概述和操作说明
    的头像 发表于 04-12 16:25 551次阅读
    Ubuntu系统快速<b class='flag-5'>上手</b>

    云服务器的maven怎么配置本地仓库?

    在云服务器上使用Maven时,你可以配置本地仓库以缓存和管理依赖项,以减少对中央仓库的依赖和加快构建过程。以下是配置Maven本地仓库的步骤: 1、选择本地仓库路径: 在云服务器上选择一个适当的目录
    的头像 发表于 02-22 16:59 533次阅读

    如何优化 PCB 布线规则

    本文要点在PCB布线中不使用规则可能会出现的问题。设计中可使用的不同类型PCB布线规则。如何在PCB布线中应用规则和约束。“限制”一词通常具有负面色彩,会引起人们的警惕。但实际上,对于
    的头像 发表于 02-19 13:00 1237次阅读
    如何优化 PCB 布线<b class='flag-5'>规则</b>?

    pcb走线的规则设置方法介绍

    线规则的设置方法,以确保设计的可靠性和性能。 一、规则的制定前提 在制定PCB走线规则之前,有几个前提需要清楚。 设备要求:首先,根据实际设备要求考虑PCB的尺寸、限制
    的头像 发表于 01-09 10:45 2593次阅读