历史项目依赖库Bugfix技巧-类覆盖

在项目维护过程中,我们可能会遇到历史项目依赖的第三方库出现BUG而需要修复的情况,而这些第三方库可能来源于公司自主开发或开源项目,但由于各种原因,这些库可能已无人维护。

此时,解决这个问题有三个办法

一、基于源码修改重新打包发布

二、某些时候可能没有源码,需要反编译进行修改再重新编译打包

三、类覆盖

本文主要分享第三种类覆盖的实现方式,用于在一些特殊情况下解决线上问题,保证项目的正常运行。

一、类覆盖的基本原理

原理如其名,通过自定义类覆盖目标类。

具体实现方式为通过定义与三方库中存在问题目标类同名的自定义类,并确保其加载优先级高于原始类。

这里特别说明下类加载优先级的控制,分两种情况

1. 直接依赖

项目直接依赖了一个库C,项目源码打包后是在classes目录下的,此种情况无需特殊控制,默认classes目录优先加载,因此自定义的类会优先于依赖库中的类加载。

2. 关联依赖

项目依赖了库B,库B又依赖了库C,如果要控制库B和库C中同名类的加载顺序,可以通过定义依赖顺序进行控制。

以SpringBoot Maven 工程为例,B依赖定义在C依赖上面,可以保证最终生成的可执行jar中classpath.idx里面定义的库加载顺序B优先于C,保证最终加载时B库中的类优先于C库加载。

xml 复制代码
<dependency>
	<groupId>org.example</groupId>
	<artifactId>B</artifactId>
	<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
  <groupId>org.example</groupId>
  <artifactId>C</artifactId>
  <version>1.0-SNAPSHOT</version>
</dependency>

二、一个示例

如下工程,有一个依赖的三方库C

C依赖库种有一个C工具类,代码如下,其中的isEmpty方法未判断null值,会导致空指针异常

typescript 复制代码
package org.c;

public class C {

    public static boolean isEmpty(String s){
        return s.isEmpty();
    }

}

主模块A类代码如下,调用了C类的isEmpty方法

typescript 复制代码
public class A {
    public static void main(String[] args ) {
        String s = "123";

        if(!C.isEmpty(s)){
            System.out.println("String is " + s);
        }

        String ss = null;
        
        if(!C.isEmpty(ss)){ // 异常位置
            System.out.println("String is " + s);
        }

    }

}

运行A类将会在异常位置处出现空指针异常。

下面使用类覆盖方法进行BUG修正。

2.1 创建同名类

在A模块种创建同名类C,如下

自定义C类的代码如下

typescript 复制代码
package org.c;

public class C {

    public static boolean isEmpty(String s){
      // 修复原始库空指针问题
      if(s == null) {
         return true;
      }

        return s.isEmpty();
    }

}

2.2 验证效果

再次运行A类,程序正常执行完成。

三、总结

首先,优先推荐前两种方式进行问题修复,但是某些时候受制于时间、成本、风险等因素需要快速解决问题,这时,可以考虑第三种方案类覆盖。

需要特别注意的是,修改的方法可能会被多处调用,修改时需要充分考虑兼容性。

相关推荐
高频因子挖掘机27 分钟前
股票池代码为什么总有问题?从常见误区到可解释的校验报告
后端·github·api
邪修king2 小时前
Re:Linux 系统篇(三十五):进程间通信Chapter2:从匿名管道到进程池:Linux 进程间通信实战(深度理解「先描述,再组织」)
java·linux·运维
拆房老料2 小时前
【第四部分:Agentic 智能体设计模式】16. 一个 Prompt 搞不定复杂任务?试试 Prompt Chaining
java·前端·人工智能·设计模式·prompt
张张123y3 小时前
后端第十四课:Agent 记忆系统(让 Agent 记住上下文和用户,跨会话不健忘)
java·大数据·人工智能·python·agent·记忆
考虑考虑7 小时前
nginx路由重写
运维·后端·自动化运维
曹牧8 小时前
C#:空合并运算符
java·前端·数据库
布吉岛的石头8 小时前
Java 程序员第 50 阶段2:预训练的目标函数:自回归语言建模本质
java·开发语言·人工智能·深度学习·回归·transformer
golang学习记8 小时前
IDEA 2026年的玩法已经完全不同
java·ide·intellij-idea
JaguarJack8 小时前
PHP 紧急修复两项严重 RCE 漏洞,8.2 至 8.5 用户应立即升级
后端·php·服务端
BingoGo9 小时前
PHP 紧急修复两项严重 RCE 漏洞,8.2 至 8.5 用户应立即升级
后端·php