You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Spring Boot获取数据库路径遇AbstractMethodError问题求助

解决Spring Boot调用接口抛出AbstractMethodError的问题

问题背景

我是Spring Boot新手,编写了一个接口打算用Postman调用获取数据库路径,代码参考自谷歌。服务启动一切正常,但调用接口时却抛出了AbstractMethodError错误,具体的控制器代码和错误信息如下:

控制器代码

import org.apache.derby.client.am.SqlException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;
import javax.sql.DataSource;
import javax.validation.Valid;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.util.List;

@RestController
@RequestMapping("/createBackup")
public class UserController {
    @Autowired
    private ApplicationContext appContext;

    @GetMapping("/getPath")
    public void getPath() {
        DataSource ds = (DataSource)appContext.getBean("dataSource");
        Connection conn = null;
        DatabaseMetaData dmd = null;
        String url = "";
        try {
            conn = ds.getConnection();
            dmd = conn.getMetaData();
            url = url + dmd.getURL();
        } catch(SQLException sqe) {
            sqe.printStackTrace();
        }
        System.out.println(url);
    }
}

错误信息

java.lang.AbstractMethodError: org.apache.derby.client.net.NetConnection.isValid(I)Z
at com.zaxxer.hikari.pool.PoolBase.checkDriverSupport(PoolBase.java:454) ~[HikariCP-3.2.0.jar:na]
at com.zaxxer.hikari.pool.PoolBase.setupConnection(PoolBase.java:421) ~[HikariCP-3.2.0.jar:na]
at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:374) ~[HikariCP-3.2.0.jar:na]
at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:198) ~[HikariCP-3.2.0.jar:na]
at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:467) ~[HikariCP-3.2.0.jar:na]
at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:541) ~[HikariCP-3.2.0.jar:na]
......

问题分析与解决方案

这个AbstractMethodError是典型的依赖版本不兼容问题:Spring Boot默认使用的HikariCP 3.2.0会调用JDBC 4.1标准里新增的Connection.isValid(int)方法,但你当前使用的Derby客户端驱动版本太旧,还没有实现这个方法,导致运行时找不到对应实现抛出错误。

给你三个可行的解决思路,按推荐程度排序:

1. 升级Derby客户端驱动版本

这是最推荐的方案,直接把Derby驱动升级到支持JDBC 4.1及以上的版本,就能从根源解决问题。找到你的依赖配置文件(Maven的pom.xml或Gradle的build.gradle),修改Derby依赖的版本:

  • Maven示例:
<dependency>
    <groupId>org.apache.derby</groupId>
    <artifactId>derbyclient</artifactId>
    <version>10.15.2.0</version> <!-- 可替换为最新稳定版 -->
</dependency>
  • Gradle示例:
implementation 'org.apache.derby:derbyclient:10.15.2.0'

2. 配置HikariCP使用自定义连接校验SQL

如果暂时无法升级Derby驱动,可以让HikariCP跳过isValid方法调用,改用指定的SQL查询来校验连接状态。在application.propertiesapplication.yml中添加以下配置:

  • application.properties:
spring.datasource.hikari.connection-test-query=SELECT 1 FROM SYSIBM.SYSDUMMY1
  • application.yml:
spring:
  datasource:
    hikari:
      connection-test-query: SELECT 1 FROM SYSIBM.SYSDUMMY1

这个SQL是Derby的标准测试查询,能替代isValid方法完成连接有效性校验。

3. 降级HikariCP版本(不推荐)

如果上面两种方案都暂时无法实施,可以临时降级HikariCP到不依赖isValid方法的旧版本,但注意旧版本可能存在安全漏洞和性能问题,仅作为临时应急方案:

  • Maven示例:
<dependency>
    <groupId>com.zaxxer</groupId>
    <artifactId>HikariCP</artifactId>
    <version>2.7.9</version>
</dependency>

额外小建议

你的代码里通过ApplicationContext获取DataSource的方式可以优化一下,直接用@Autowired注入更符合Spring的依赖注入规范,代码也更简洁,另外记得加上finally块关闭数据库连接避免资源泄漏:

@RestController
@RequestMapping("/createBackup")
public class UserController {
    @Autowired
    private DataSource dataSource; // 直接注入

    @GetMapping("/getPath")
    public void getPath() {
        Connection conn = null;
        DatabaseMetaData dmd = null;
        String url = "";
        try {
            conn = dataSource.getConnection();
            dmd = conn.getMetaData();
            url = url + dmd.getURL();
        } catch(SQLException sqe) {
            sqe.printStackTrace();
        } finally {
            // 关闭连接,避免资源泄漏
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        System.out.println(url);
    }
}

内容的提问来源于stack exchange,提问作者Vai

火山引擎 最新活动