You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用JDBI声明式风格时出现ClassNotFoundException问题求助

问题:JDBI声明式风格抛出NoClassDefFoundError,流式风格正常运行

问题描述

尝试使用JDBI的声明式风格(SqlObject)从数据库表获取数据时,抛出java.lang.ClassNotFoundException: org.jdbi.v3.core.extension.ExtensionContext错误,但使用流式风格时可以正常运行。以下是相关配置与代码:

POM依赖配置

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
    <version>3.0.1</version>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
    <groupId>org.jdbi</groupId>
    <artifactId>jdbi3-core</artifactId>
    <version>3.19.0</version>
</dependency>
<dependency>
    <groupId>org.jdbi</groupId>
    <artifactId>jdbi3-sqlobject</artifactId>
    <version>3.35.0</version>
</dependency>

<dependency>
    <groupId>org.apache.derby</groupId>
    <artifactId>derby</artifactId>
    <version>10.13.1.1</version>
</dependency>

<dependency>
    <groupId>org.apache.derby</groupId>
    <artifactId>derbyclient</artifactId>
    <version>10.13.1.1</version>
</dependency>

Jdbi Bean注册代码

@Bean
public Jdbi jdbi(DataSource ds, List<JdbiPlugin> jdbiPlugins, List<RowMapper<?>> rowMappers) {
    TransactionAwareDataSourceProxy proxy = new TransactionAwareDataSourceProxy(ds);
    Jdbi jdbi = Jdbi.create(ds);
    jdbi.installPlugin(new SqlObjectPlugin());

    return jdbi;
}

DAO接口代码

public interface FolioDao {

    @SqlQuery("select * from FOLIO")
    @UseRowMapper(FolioMapper.class)
    List<Folio> findAll();

}

Service调用代码

public Iterable<Folio> getAllFolio(Jdbi jdbi) {
    return jdbi.withExtension(FolioDao.class, dao -> dao.findAll());
}

错误堆栈信息

java.lang.ClassNotFoundException: org.jdbi.v3.core.extension.ExtensionContext
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641) ~[na:na]
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) ~[na:na]
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521) ~[na:na]
    at org.jdbi.v3.sqlobject.internal.SqlObjectInitData.lambda$lazyInvoker$0(SqlObjectInitData.java:129) ~[jdbi3-sqlobject-3.35.0.jar:3.35.0]
    at org.jdbi.v3.core.internal.MemoizingSupplier.init(MemoizingSupplier.java:42) ~[jdbi3-core-3.19.0.jar:3.19.0]
    at org.jdbi.v3.core.internal.MemoizingSupplier.get(MemoizingSupplier.java:36) ~[jdbi3-core-3.19.0.jar:3.19.0]
    at org.jdbi.v3.sqlobject.SqlObjectFactory.lambda$attach$2(SqlObjectFactory.java:107) ~[jdbi3-sqlobject-3.35.0.jar:3.35.0]
    at jdk.proxy2/jdk.proxy2.$Proxy67.findAll(Unknown Source) ~[na:na]
    at com.chakra.projects.investment.service.funds.FundManagerSvc.lambda$getAllFolio$0(FundManagerSvc.java:28) ~[classes/:na]
    at org.jdbi.v3.core.Jdbi.callWithExtension(Jdbi.java:476) ~[jdbi3-core-3.19.0.jar:3.19.0]
    at org.jdbi.v3.core.Jdbi.withExtension(Jdbi.java:463) ~[jdbi3-core-3.19.0.jar:3.19.0]
    at com.chakra.projects.investment.service.funds.FundManagerSvc.getAllFolio(FundManagerSvc.java:28) ~[classes/:na]
    at com.chakra.projects.investment.controllers.FundManagerController.getAll(FundManagerController.java:29) ~[classes/:na]
    at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:578) ~[na:na]

排查方向与解决方案

  • 核心问题:JDBI组件版本不一致
    当前依赖中jdbi3-core版本为3.19.0,而jdbi3-sqlobject版本为3.35.0,两者版本差异过大。ExtensionContext类存在于较高版本的jdbi3-core中,低版本core组件缺少该类,导致sqlobject组件调用时抛出ClassNotFoundException。

  • 解决方案
    统一所有JDBI相关依赖的版本,将jdbi3-core升级到与jdbi3-sqlobject一致的3.35.0:

    <dependency>
        <groupId>org.jdbi</groupId>
        <artifactId>jdbi3-core</artifactId>
        <version>3.35.0</version>
    </dependency>
    <dependency>
        <groupId>org.jdbi</groupId>
        <artifactId>jdbi3-sqlobject</artifactId>
        <version>3.35.0</version>
    </dependency>
    
  • 额外验证点

    1. 执行mvn dependency:tree命令检查依赖树,确认没有其他版本的JDBI组件被间接引入
    2. 清理Maven本地仓库中冲突的JDBI依赖,重新构建项目
    3. 确认SqlObjectPlugin已正确安装到Jdbi实例中(你的代码已完成此操作,无需修改)

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 06:00:59