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

    浏览量

    3993
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    图扑软件 3D 场景预加载应用实现

    加载是在进入正式场景之前提前加载所需模型、材质、图片等资源的技术手段,其核心价值在于消除资源加载等待,确保场景首次渲染即可完整呈现,从而提供无缝、流畅的用户体验。在复杂的 Web 3D 可视化
    的头像 发表于 12-01 16:04 75次阅读
    图扑软件 3D 场景预<b class='flag-5'>加载</b>应用实现

    电池气密性检测设备使用误区,90%的人都踩过-岳信仪器

    操作人员认为,只要电池气密性检测设备能正常运行,就不需要频繁校准。实际上,气密性检测设备的精度会随着使用时间和环境因素发生变化。如果不定期校准,检测结果可能会出现
    的头像 发表于 11-28 10:41 107次阅读
    电池<b class='flag-5'>包</b>气密性检测设备使用误区,90%的人都踩过-岳信仪器

    RTthread怎么加载zynq的支持

    RTthread有xilinx zynq的芯片支持包了么,SDK管理器里面怎么下载ZYNQ的支持呢?求助
    发表于 09-23 06:05

    如何解决RT-Thread 编译冲突,DIR 类型在 ff.h 与 dirent.h 中重复定义?

    软件时,编译出现如下冲突: 具体是: dfs/elmfat/ff.h 中定义了 FatFS 的 DIR 结构体 libc/dirent.h 中也定义了 POSIX 的 DIR 结构体 导致冲突编译
    发表于 09-16 06:16

    编程软件连接PLC出现IP冲突时如何解决?

    一般来说,每个PLC都有自己的IP地址,用以和其他设备进行通信。而如果同一网络出现相同IP的设备,就会导致IP冲突、数据丢或ping不通等问题。而如果IP地址没有冲突,不在一个网段内的设备也是无法
    的头像 发表于 07-31 17:08 826次阅读
    编程软件连接PLC出现IP<b class='flag-5'>冲突</b>时如何解决?

    CNC的IP地址相同冲突如何解决?

    的IP地址,这就极易引发IP地址冲突问题。当这些设备接入车间网络时,IP冲突会导致数据采集不上来,物联网平台缺乏数据来源,严重影响数字化车间的建设。 通常,设备被设置相同IP地址,是厂家在出厂前方便质检与测试,这种做法在单机
    的头像 发表于 07-23 14:13 441次阅读
    CNC的IP地址相同<b class='flag-5'>冲突</b>如何解决?

    CC\\-Link IE转Modbus TCP:风电设备通信的“双语模式”

    、波特率及映射规则即可。 案例:风电场的实际问题与解决 问题描述:某风电项目中,风机变流器(Modbus TCP)需将实时功率数据(1秒/次)上传至基于CC-Link IE的中控系统。初期测试发现
    发表于 07-07 14:45

    ArkUI-X通过Stage模型开发Android端应用指南(一)

    arkui_android_adapter.jar所提供的StageApplication。StageApplication用于初始化资源路径以及加载配置信息,例如: package
    发表于 06-24 22:16

    鸿蒙5开发宝藏案例分享---优化应用体积大小问题

    ;gt; 代码,内重复。 ✅ HSP动态 :所有HAP共享同一份HSP代码,物理存储仅1份。效果 :资源越多,节省越显著(尤其图片、公共组件库)。 ?3. OHPM依赖冲突解决:告别重复编译
    发表于 06-13 10:09

    业务监控—一站式搭建jmeter+telegraf+influxdb+Grafana看板

    一、前言 当前所测试业务需求为集成在业务系统WMS的jarjar测试主要集中在本地拉取开发编写的代码做单元测试,因为jar
    的头像 发表于 05-27 14:40 1102次阅读
    业务监控—一站式搭建jmeter+telegraf+influxdb+Grafana看板

    HarmonyOS优化应用体积大小问题性能优化

    和资源,消除使用HAR静态共享造成的多(HAP、HSP)间代码和资源的重复拷贝,从而减小应用大小。 使用ohpm的override机制或者开启resolve_conflict解决依赖冲突
    发表于 05-20 14:50

    TwinCAT3 EtherCAT抓 | 技术集结

    在使用TwinCAT测试EtherCATEOE功能时,我们会发现正常是无法使用Wireshark去进行网络抓抓取EtherCAT报文的,今天这篇文章就带大家来上手EtherCAT抓方式。准备环境
    的头像 发表于 05-15 18:04 5168次阅读
    TwinCAT3 EtherCAT抓<b class='flag-5'>包</b> | 技术集结

    Venue快速上手指南

    电子发烧友网站提供《Venue快速上手指南.pdf》资料免费下载
    发表于 03-26 14:34 0次下载

    工业数据采集如何避免IP冲突问题

    扩展或老旧设备接入时,重复冲突的IP地址会导致通信网络通信混乱、数据丢、通信延迟甚至中断,严重影响数据采集的实时性和准确性。 为此,采用有效的技术手段避免IP冲突显得尤为重要,物通博联推出基于网段隔离器(NAT网关)
    的头像 发表于 03-06 10:12 664次阅读

    Stellaris引导加载程序用户指南

    电子发烧友网站提供《Stellaris引导加载程序用户指南.pdf》资料免费下载
    发表于 12-23 16:24 0次下载
    Stellaris引导<b class='flag-5'>加载</b>程序用户指南