jdbideclarative

JDBi Declarative style - class not found


I am trying to use the declarative style of JDBI to get data from the table. It is failing with the NoClassDefFoundError.

When i tried with Fluet style in JDBI, it works fine.

POM.xml

<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>

Registerd the SqlObject plugin

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

        return jdbi;
    }

DOA

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());

    }

error

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]

I am not sure what am i missing. Any pointers on how to proceed with debugging this issue?

thanks in advance.


Solution

  • Change your Jdbi POM dependencies for jdbi3-core and jdbi3-sqlobject so they are using the same version.

    Currently you have version 3.19.0 for Jdbi Core - which does not contain org.jdbi.v3.core.extension.ExtensionContext.

    However, that class does exist in Jdbi Core version 3.35.0.


    If you remove the jdbi3-core dependency from your POM and just leave the jdbi3-sqlobject dependency, then Maven will automatically pull in the correct jdbi3-core dependency for you (it is a transitive dependency). That version of jdbi3-core will match the version of jdbi3-sqlobject.

    You can see this in the relevant Maven Central listing.