Search code examples
cdiquarkusjdbi

Quarkus and JDBI integration: Unsatisfied dependency for type javax.sql.DataSource and qualifiers [@Default]


I'm trying to use Quarkus and JDBI — not so many examples on this out there I would say :/

The Gradle script has these dependencies:

dependencies {
  implementation(enforcedPlatform("io.quarkus:quarkus-universe-bom:2.1.3.Final"))
  implementation(enforcedPlatform("org.jdbi:jdbi3-bom:3.21.0"))

  implementation("org.jdbi:jdbi3-core")
  implementation("org.jdbi:jdbi3-sqlobject")

  runtimeOnly("io.quarkus:quarkus-config-yaml")
  runtimeOnly("io.quarkus:quarkus-flyway")
  runtimeOnly("io.quarkus:quarkus-jdbc-h2")
  ...
}

I have a class to configure (and integrate) JDBI:

@ApplicationScoped
public class PersistenceConfig {
  @Inject
  DataSource dataSource;

  @Singleton
  public Jdbi jdbi() {
    return Jdbi.create(dataSource)
        .installPlugin(new SqlObjectPlugin());
  }

  @Produces
  public ActorRepository actorRepository(final Jdbi jdbi) {
    return jdbi.onDemand(ActorRepository.class);
  }
}

And I think the problem is somehow within that one (and the datasource), because I'm currently getting this error when starting the application:

2021-08-27 11:31:32,852 ERROR [io.qua.dep.dev.IsolatedDevModeMain] (main) Failed to start quarkus: java.lang.RuntimeException: io.quarkus.builder.BuildException: Build failure: Build failed due to errors
    [error]: Build step io.quarkus.arc.deployment.ArcProcessor#validate threw an exception: javax.enterprise.inject.spi.DeploymentException: javax.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type javax.sql.DataSource and qualifiers [@Default]
    - java member: org.acme.config.PersistenceConfig#dataSource
    - declared on CLASS bean [types=[java.lang.Object, org.acme.config.PersistenceConfig], qualifiers=[@Default, @Any], target=org.acme.config.PersistenceConfig]
    at io.quarkus.arc.processor.BeanDeployment.processErrors(BeanDeployment.java:1094)
    at io.quarkus.arc.processor.BeanDeployment.init(BeanDeployment.java:259)
    at io.quarkus.arc.processor.BeanProcessor.initialize(BeanProcessor.java:129)
    at io.quarkus.arc.deployment.ArcProcessor.validate(ArcProcessor.java:418)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at io.quarkus.deployment.ExtensionLoader$2.execute(ExtensionLoader.java:820)
    at io.quarkus.builder.BuildContext.run(BuildContext.java:277)
    at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18)
    at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2449)
    at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1478)
    at java.base/java.lang.Thread.run(Thread.java:829)
    at org.jboss.threads.JBossThread.run(JBossThread.java:501)
Caused by: javax.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type javax.sql.DataSource and qualifiers [@Default]
Caused by: javax.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type javax.sql.DataSource and qualifiers [@Default]

    - java member: org.acme.config.PersistenceConfig#dataSource
    - declared on CLASS bean [types=[java.lang.Object, org.acme.config.PersistenceConfig], qualifiers=[@Default, @Any], target=org.acme.config.PersistenceConfig]
    at io.quarkus.arc.processor.Beans.resolveInjectionPoint(Beans.java:492)
    at io.quarkus.arc.processor.BeanInfo.init(BeanInfo.java:463)
    at io.quarkus.arc.processor.BeanDeployment.init(BeanDeployment.java:247)
    ... 13 more

    at io.quarkus.runner.bootstrap.AugmentActionImpl.runAugment(AugmentActionImpl.java:415)
    at io.quarkus.runner.bootstrap.AugmentActionImpl.createInitialRuntimeApplication(AugmentActionImpl.java:275)
    at io.quarkus.runner.bootstrap.AugmentActionImpl.createInitialRuntimeApplication(AugmentActionImpl.java:66)
    at io.quarkus.deployment.dev.IsolatedDevModeMain.firstStart(IsolatedDevModeMain.java:91)
    at io.quarkus.deployment.dev.IsolatedDevModeMain.accept(IsolatedDevModeMain.java:424)
    at io.quarkus.deployment.dev.IsolatedDevModeMain.accept(IsolatedDevModeMain.java:64)
    at io.quarkus.bootstrap.app.CuratedApplication.runInCl(CuratedApplication.java:136)
    at io.quarkus.bootstrap.app.CuratedApplication.runInAugmentClassLoader(CuratedApplication.java:93)
    at io.quarkus.deployment.dev.DevModeMain.start(DevModeMain.java:145)
    at io.quarkus.deployment.dev.DevModeMain.main(DevModeMain.java:63)
Caused by: io.quarkus.builder.BuildException: Build failure: Build failed due to errors
Caused by: io.quarkus.builder.BuildException: Build failure: Build failed due to errors

    [error]: Build step io.quarkus.arc.deployment.ArcProcessor#validate threw an exception: javax.enterprise.inject.spi.DeploymentException: javax.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type javax.sql.DataSource and qualifiers [@Default]
    - java member: org.acme.config.PersistenceConfig#dataSource
    - declared on CLASS bean [types=[java.lang.Object, org.acme.config.PersistenceConfig], qualifiers=[@Default, @Any], target=org.acme.config.PersistenceConfig]
    at io.quarkus.arc.processor.BeanDeployment.processErrors(BeanDeployment.java:1094)
    at io.quarkus.arc.processor.BeanDeployment.init(BeanDeployment.java:259)
    at io.quarkus.arc.processor.BeanProcessor.initialize(BeanProcessor.java:129)
    at io.quarkus.arc.deployment.ArcProcessor.validate(ArcProcessor.java:418)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at io.quarkus.deployment.ExtensionLoader$2.execute(ExtensionLoader.java:820)
    at io.quarkus.builder.BuildContext.run(BuildContext.java:277)
    at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18)
    at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2449)
    at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1478)
    at java.base/java.lang.Thread.run(Thread.java:829)
    at org.jboss.threads.JBossThread.run(JBossThread.java:501)
Caused by: javax.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type javax.sql.DataSource and qualifiers [@Default]
Caused by: javax.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type javax.sql.DataSource and qualifiers [@Default]

    - java member: org.acme.config.PersistenceConfig#dataSource
    - declared on CLASS bean [types=[java.lang.Object, org.acme.config.PersistenceConfig], qualifiers=[@Default, @Any], target=org.acme.config.PersistenceConfig]
    at io.quarkus.arc.processor.Beans.resolveInjectionPoint(Beans.java:492)
    at io.quarkus.arc.processor.BeanInfo.init(BeanInfo.java:463)
    at io.quarkus.arc.processor.BeanDeployment.init(BeanDeployment.java:247)
    ... 13 more

    at io.quarkus.builder.Execution.run(Execution.java:116)
    at io.quarkus.builder.BuildExecutionBuilder.execute(BuildExecutionBuilder.java:79)
    at io.quarkus.deployment.QuarkusAugmentor.run(QuarkusAugmentor.java:151)
    at io.quarkus.runner.bootstrap.AugmentActionImpl.runAugment(AugmentActionImpl.java:413)
    ... 9 more
Caused by: javax.enterprise.inject.spi.DeploymentException: javax.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type javax.sql.DataSource and qualifiers [@Default]
Caused by: javax.enterprise.inject.spi.DeploymentException: javax.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type javax.sql.DataSource and qualifiers [@Default]

    - java member: org.acme.config.PersistenceConfig#dataSource
    - declared on CLASS bean [types=[java.lang.Object, org.acme.config.PersistenceConfig], qualifiers=[@Default, @Any], target=org.acme.config.PersistenceConfig]
    at io.quarkus.arc.processor.BeanDeployment.processErrors(BeanDeployment.java:1094)
    at io.quarkus.arc.processor.BeanDeployment.init(BeanDeployment.java:259)
    at io.quarkus.arc.processor.BeanProcessor.initialize(BeanProcessor.java:129)
    at io.quarkus.arc.deployment.ArcProcessor.validate(ArcProcessor.java:418)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at io.quarkus.deployment.ExtensionLoader$2.execute(ExtensionLoader.java:820)
    at io.quarkus.builder.BuildContext.run(BuildContext.java:277)
    at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18)
    at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2449)
    at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1478)
    at java.base/java.lang.Thread.run(Thread.java:829)
    at org.jboss.threads.JBossThread.run(JBossThread.java:501)
Caused by: javax.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type javax.sql.DataSource and qualifiers [@Default]
Caused by: javax.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type javax.sql.DataSource and qualifiers [@Default]

    - java member: org.acme.config.PersistenceConfig#dataSource
    - declared on CLASS bean [types=[java.lang.Object, org.acme.config.PersistenceConfig], qualifiers=[@Default, @Any], target=org.acme.config.PersistenceConfig]
    at io.quarkus.arc.processor.Beans.resolveInjectionPoint(Beans.java:492)
    at io.quarkus.arc.processor.BeanInfo.init(BeanInfo.java:463)
    at io.quarkus.arc.processor.BeanDeployment.init(BeanDeployment.java:247)
    ... 13 more

I can't fully comprehend why the datasource cannot be injected since I already have it configured in the YAML file:

quarkus:
  datasource:
    db-kind: "h2"
    jdbc:
      url: "jdbc:h2:mem:java_quarkus_graphql;DB_CLOSE_DELAY=-1;MODE=PostgreSQL"
    username: "sa"
  flyway:
    clean-disabled: true
    locations: "classpath:database/migration"
    migrate-at-start: true
    validate-on-migrate: true

I read the guide around this subject and it should be available as AgroalDataSource — or just DataSource.


UPDATE #1

By the way, this setup/configuration works if I use an older version (1.13.4.Final) of Quarkus:

> Task :quarkusDev
Listening for transport dt_socket at address: 5005
__  ____  __  _____   ___  __ ____  ______ 
 --/ __ \/ / / / _ | / _ \/ //_/ / / / __/ 
 -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \   
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/   
2021-08-27 12:55:39,840 |- INFO  in io.quarkus:88 [Quarkus Main Thread] - java-quarkus-graphql 0.1.2-SNAPSHOT on JVM (powered by Quarkus 1.13.4.Final) started in 0.770s. Listening on: http://localhost:8080
2021-08-27 12:55:39,843 |- INFO  in io.quarkus:91 [Quarkus Main Thread] - Profile dev activated. Live Coding activated.
2021-08-27 12:55:39,843 |- INFO  in io.quarkus:92 [Quarkus Main Thread] - Installed features: [agroal, cdi, config-yaml, flyway, hibernate-validator, jdbc-h2, mutiny, narayana-jta, smallrye-context-propagation, smallrye-graphql]

UPDATE #2

Version 2.2.1.Final doesn't have the issue when starting the application, but somehow it fails when running the test cases:

@Stereotype
@QuarkusTest
@Transactional
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface QuarkusTransactionalTest {
  // ...
}
@QuarkusTransactionalTest
final class ActorRepositoryTest {
  @Inject
  ActorRepository repository;

  @Test
  void findById_WhenActorDoesNotExist() {
    Assertions.assertThat(repository.findById(UUID.fromString("c6b1d415-77ee-49c2-b912-fbd00e07702b"))).isNotPresent();
  }

  @Test
  void findById_WhenActorExist() {
    Assertions.assertThat(repository.findById(UUID.fromString("3bea7318-bb7a-4232-9343-59579dd5b2a2")))
        .contains(ActorFactory.penelopeGuiness());
  }
}
ActorRepositoryTest > findById_WhenActorExist() FAILED
    java.lang.RuntimeException: java.lang.RuntimeException: io.quarkus.builder.BuildException: Build failure: Build failed due to errors
        [error]: Build step io.quarkus.arc.deployment.ArcProcessor#validate threw an exception: javax.enterprise.inject.spi.DeploymentException: javax.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type javax.sql.DataSource and qualifiers [@Default]
        - java member: org.acme.config.PersistenceConfig#dataSource
        - declared on CLASS bean [types=[java.lang.Object, org.acme.config.PersistenceConfig], qualifiers=[@Default, @Any], target=org.acme.config.PersistenceConfig]
        at io.quarkus.arc.processor.BeanDeployment.processErrors(BeanDeployment.java:1100)
        at io.quarkus.arc.processor.BeanDeployment.init(BeanDeployment.java:265)
        at io.quarkus.arc.processor.BeanProcessor.initialize(BeanProcessor.java:129)
        at io.quarkus.arc.deployment.ArcProcessor.validate(ArcProcessor.java:418)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at io.quarkus.deployment.ExtensionLoader$2.execute(ExtensionLoader.java:820)
        at io.quarkus.builder.BuildContext.run(BuildContext.java:277)
        at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18)
        at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2449)
        at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1478)
        at java.base/java.lang.Thread.run(Thread.java:829)
        at org.jboss.threads.JBossThread.run(JBossThread.java:501)
    Caused by: javax.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type javax.sql.DataSource and qualifiers [@Default]
        - java member: org.acme.config.PersistenceConfig#dataSource
        - declared on CLASS bean [types=[java.lang.Object, org.acme.config.PersistenceConfig], qualifiers=[@Default, @Any], target=org.acme.config.PersistenceConfig]
        at io.quarkus.arc.processor.Beans.resolveInjectionPoint(Beans.java:492)
        at io.quarkus.arc.processor.BeanInfo.init(BeanInfo.java:471)
        at io.quarkus.arc.processor.BeanDeployment.init(BeanDeployment.java:253)
        ... 13 more

Solution

  • Fixed with latest (2.2.3.Final) version.