当前位置: 首页 > news >正文

解决引入第三方SDK导致的依赖冲突问题

出现问题:

原因:导入第三方sdk

解决思路:刷新maven,清理,排除依赖

在排除掉可能的依赖后发现还是不行,分析依赖关系,打开idea自带的maven树查看工具:

通过maven依赖图谱我们发现,所有的日志依赖都来源于spring-boot-starter,这也是Springboot的祖宗依赖,并且,该sdk是一整个完整的SpringBoot工程,而不是常见的模块式。

直接排他祖宗:

问题解决,分析出现原因:

根本原因:jvm的类加载机制

问题产生过程:两个项目的依赖版本不同,假设我们项目是:

<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.10</version>
</dependency>

引入的第三方sdk中的依赖是:

<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.3</version>
</dependency>

Spring Boot 启动时,类加载器的行为如下:

步骤 1:类加载器扫描 classpath

Spring Boot 启动时,ApplicationClassLoader 负责扫描 classpath 下的 JAR 文件,发现:

  • logback-classic-1.2.10.jar(来自我们的项目依赖)

  • logback-classic-1.2.3.jar(来自 SDK)

Java 规定 同一个类(全限定名相同),只能被一个类加载器加载一次,否则会导致冲突。

步骤 2:类加载器加载 SLF4J

SLF4J 主要涉及以下类:

  • org.slf4j.LoggerFactory (SLF4J 的核心类)

  • org.slf4j.impl.StaticLoggerBinder(绑定具体日志实现)

Spring Boot 在初始化日志时,会执行:

Logger logger = LoggerFactory.getLogger(MyApp.class);

这时,类加载器会加载 org.slf4j.impl.StaticLoggerBinder 类,而这个类分别存在于:

  • logback-classic-1.2.10.jar

  • logback-classic-1.2.3.jar

假设 ApplicationClassLoader 先加载 logback-classic-1.2.3.jar,这时 JVM 缓存了老版本,但你的 logback-classic-1.2.10.jar 中的方法签名可能发生了变化。


3. 发生 AbstractMethodError 的原因

由于 logback-classic-1.2.3.jar较早的版本,它可能没有某些方法,比如:

// 1.2.3 版本的方法
public boolean supportsSourceType(Class<?> sourceType) { return true; }
​
// 1.2.10 版本方法(升级后可能有不同签名)
public boolean supportsSourceType(Class<?> sourceType, boolean flag) { return true; }

然后 Spring Boot 依赖的是 logback-classic-1.2.10.jar 版本的方法:

listenerAdapter.supportsSourceType(someClass);

但由于 logback-classic-1.2.3.jar 已经被类加载器加载,JVM 仍然调用的是老版本的方法,而 logback-classic-1.2.3.jar 里没有这个方法,就会发生 AbstractMethodError

Exception in thread "main" java.lang.AbstractMethodError
    at org.springframework.context.event.GenericApplicationListenerAdapter.supportsSourceType

总结:

  1. 类加载器只能加载一个类的一个版本,如果 logback-classic-1.2.3.jar 先被加载,Spring Boot 调用新版本的方法就会失败。

  2. 方法签名变化导致 AbstractMethodError,因为类加载器仍然引用的是旧的 logback-classic-1.2.3.jar 版本,而新代码需要 1.2.10 的方法。

  3. 该SDK是完整的SpringBoot工程,而不是模块,模块化 SDK 可以通过适当的 类加载器管理、依赖管理、版本对齐 等方式,确保它的日志框架不会影响到 Spring Boot 项目的日志实现

相关文章:

  • .gitignore中忽略node_modules
  • 2.11 sqlite3数据库【数据库的相关操作指令、函数】
  • 编程技巧:VUE 实现接口返回数据的流式处理
  • 算法——对比A*算法与IDA*算法
  • Golang GORM系列:GORM数据库迁移
  • AI软件栈:LLVM分析(五)
  • Git标签管理:从基础到高阶自动化实践
  • 第6章 6.4 ASP.NET Core Web API各种技术及选择
  • 人工智能算法python程序运行环境安装步骤整理
  • 贪心算法(Greedy Algorithm)
  • AI前端开发与云计算结合:效率革命,ScriptEcho引领未来
  • 网络安全设备异构要求 网络安全设备硬件
  • NetworkX布局算法:nx.spring_layout
  • ADC入门准备(十):信号与系统知识回顾
  • 算法16(力扣451)——根据字符出现频率排序
  • 使用 Python 爬虫获取微店快递费用 item_fee API 接口数据
  • SolidWorks速成教程P3-3【零件 | 第三节】——草图绘制面实线与构造线的区别
  • 贪心算法_翻硬币
  • React中Fragment的使用
  • [Windows] NVIDIA显卡驱动安装去除其中垃圾程序,NVCleanstall
  • 欧盟拟对发往欧洲的小额包裹加收手续费,外交部回应
  • 以色列“全面接管”加沙“雷声大雨点小”:援助政策引内讧,美欧失去耐心
  • 管教打骂9岁儿子致其死亡,青岛一男子被刑拘
  • 越秀地产约41.49亿元出售北京海淀功德寺项目公司65%股权,此前已质押给华润置地
  • 集齐中国泳坛“老中青”!200自潘展乐力压汪顺、孙杨夺冠
  • 学生靠老干妈下饭、职工餐肉类又多又好?纪委出手整治