quarkus: Failures when accessing uninitialized RUNTIME_INIT synthetic beans during STATIC_INIT

Recently, there were several issues following the same pattern:

  1. An extension A provides a RUNTIME_INIT synthetic bean for type Foo
    • such a bean is initialized during the RUNTIME_INIT bootstrap phase
    • see also io.quarkus.arc.deployment.SyntheticBeanBuildItem.ExtendedBeanConfigurator.setRuntimeInit()
  2. An extension B initializes a CDI component Bar during STATIC_INIT; and Bar depends on Foo
  3. If Foo is a normal scope (e.g. @ApplicationScoped) the injection works fine unless Bar attempts to use Foo, i.e. call a method
    • in this case we throw an exception with message: Synthetic bean instance not initialized yet
  4. If Foo is @Singleton then the injection always fails with Synthetic bean instance not initialized yet

So far I saw JAX-RS providers ~and gRPC endpoints~ to fail because of this limitation, i.e. a JAX-RS provider ~gRPC~ injects a bean that touches the injected Vertx instance.

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 17 (11 by maintainers)

Commits related to this issue

Most upvoted comments

@Felk does the MyValidator inject the AgroalDataSource directly? If so then replace the injection point with @Inject javax.enterprise.inject.Instance<AgroalDataSource> and then Instance.get() to obtain the DS instance. You can even try @WithCaching if you need better performance.

@mkouba Yes, thank you! After some more tinkering it was indeed the DataSource and not the EntityManager that was causing the problem. Thankfully one of the classes in the inject chain in-between is under my control so I could apply your suggestion, injecting Instance<DataSource> instead of DataSource directly.

The gRPC service, but it’s expected: from the gRPC-quarkus documentation, you cannot use @ApplicationScoped annotation but must use @Singleton since the gRPC service implementation cannot be proxied.

I see. Well, you can try to @Inject javax.enterprise.inject.Instance<AgroalDataSource> ds and then ds.get() in your gRPC service as a workaround.