Caused by: java.lang.NoSuchFieldError: exceptionOverride

当项目遇到SQL报错且无法显示详细信息时,作者通过日志定位到HikariCP的ProxyConnection类。发现该类缺少特定属性,从而导致问题。为了解决这个问题,作者选择了修改字节码的方式,在`checkException`方法中插入日志打印代码,以便捕获和记录详细的异常信息。通过引入javassist库,实现了动态修改字节码并成功增加了日志输出功能。

项目报错,导致sql报错信息无法展示详细内容。

通过日志,定位到是这一行代码(at com.zaxxer.hikari.pool.ProxyConnection.checkException(ProxyConnection.java:159)
),直接找到这个方法,查看原因。 

发现端倪,这个属性没有变颜色,实际中可通过debug排查。 

找到这个类,发现确实没有这个属性,真相大白。

解决方案:

1、换新版本
2、修改字节码,由于项目用的gbase8s数据库,项目整个依赖很乱,所以我选择方案二,直接修改字节码文件,添加一行打印日志。

        这是maven依赖,如果你用的是mybatis,那么这个依赖不需要,直接使用mybatis中的即可,无非是包名变了下。

<dependencies>
    <dependency>
        <groupId>org.javassist</groupId>
        <artifactId>javassist</artifactId>
        <version>3.28.0-GA</version>
    </dependency>
</dependencies>

        下面是代码:

        项目启动的时候执行一下即可。


import org.apache.ibatis.javassist.*;

import java.io.IOException;

public class GbaseLogHandler {

    public static void addLog() {
        try {
            ClassPool pool = ClassPool.getDefault();
            // 替换为目标类的完整类名
            CtClass targetClass = pool.get("com.zaxxer.hikari.pool.ProxyConnection");

            CtMethod targetMethod = targetClass.getDeclaredMethod("checkException");
            String logCode = "LOGGER.error(\"拦截gbase checkException 发现异常 errMsg:{}\",$1.getMessage(),$1);";
            targetMethod.insertBefore(logCode);

            targetClass.toBytecode();
            pool.toClass(targetClass);
        } catch (NotFoundException | CannotCompileException | IOException e) {
            throw new RuntimeException(e);
        }

    }
}

        然后就可以看到真正的报错日志了。

 

### Java中 `java.lang.NoSuchFieldError: VERTICA` 错误的原因分析 `java.lang.NoSuchFieldError: VERTICA` 是一种运行时异常,通常发生在尝试访问某个类中的字段时,而该字段在当前版本的类定义中不存在。这种错误通常是由于类加载器加载了不兼容的不同版本的类文件引起的。 以下是可能导致此问题的具体原因: 1. **依赖冲突** 如果项目中有多个不同版本的库被引入,可能会导致某些类的字段在编译时存在但在运行时缺失的情况[^1]。例如,如果两个不同的库都提供了同一个类(如 `VERTICA`),但它们的实现细节有所不同,则可能引发此类错误。 2. **字节码操作工具的影响** 使用像 ASM 或 Javassist 这样的字节码操作框架修改类结构时,如果没有正确更新所有相关联的部分,也可能导致字段丢失或不可用的问题[^2]。 3. **静态变量初始化失败** 当程序试图通过反射或其他方式获取名为 `VERTICA` 的静态成员却找不到它时会抛出这个异常。这可能是由于实际代码里根本没有声明这样一个常量或者它的名称拼写有误造成的。 针对以上提到的各种可能性,可以采取相应的措施来解决问题: #### 解决方案一:检查并清理Maven/Gradle构建配置 确保项目的构建工具只拉取所需的确切版本号的外部依赖项而不是最新版或者其他变体形式。可以通过执行命令如下所示来进行排查: ```bash mvn dependency:tree -Dverbose=true -Dincludes=<conflicting-library> ``` #### 解决方案二:验证所使用的第三方库及其API文档 确认正在调用的方法签名以及参数列表完全匹配官方发布的资料说明;必要情况下升级至更稳定的新发行版本以获得更好的支持和服务质量保障. #### 解决方案三:重新编译整个工程 有时候即使解决了表面上看起来像是引起问题的根本所在之后仍然无法彻底消除报错现象,这时不妨考虑全盘抹掉本地缓存再做一次完整的重新组装过程试试看效果如何. ```bash rm -rf ~/.m2/repository/ mvn clean install ``` --- ### 示例代码片段展示潜在风险区域 下面给出一段可能存在隐患的例子供参考学习之用: ```java public class DatabaseConstants { public static final String CONNECTION_TYPE_MYSQL = "MYSQL"; // 注意这里缺少了 VERTICA 定义 } // 可能会在其他地方这样引用 String dbType = DatabaseConstants.CONNECTION_TYPE_VERTICA; System.out.println(dbType); ``` 上述例子中假如忘记添加对于 `CONNECTION_TYPE_VERTICA` 的正确定义就会触发类似的 `NoSuchFieldError`. ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值