使用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>额外验证点
- 执行
mvn dependency:tree命令检查依赖树,确认没有其他版本的JDBI组件被间接引入 - 清理Maven本地仓库中冲突的JDBI依赖,重新构建项目
- 确认
SqlObjectPlugin已正确安装到Jdbi实例中(你的代码已完成此操作,无需修改)
- 执行
内容的提问来源于stack exchange,提问作者user3602300
相关产品推荐
相关产品推荐

