I have a Quarkus extension targeting Quarkus 2.16.4.Final which has a DynamicFeature which needs runtime beans to run its configure
method. I saw a related question here, where the answer says to use Arc.container().instance(...)
to access the bean. However, the bean I need is a runtime bean that depends on a runtime Config from another extension, so it fails at build time with this error. How do I register a DynamicFeature with resteasy-reactive?
DynamicFeature implementation:
package mypackage;
import io.quarkus.arc.Arc;
import javax.ws.rs.container.DynamicFeature;
import javax.ws.rs.container.ResourceInfo;
import javax.ws.rs.core.FeatureContext;
import javax.ws.rs.ext.Provider;
@Provider
public class MyDynamicFeature implements DynamicFeature {
@Override
public void configure(ResourceInfo resourceInfo, FeatureContext context) {
MyAnnotation annot = resourceInfo.getResourceMethod().getAnnotation(MyAnnotation.class);
if (annot == null) {
annot = resourceInfo.getResourceClass().getAnnotation(MyAnnotation.class);
}
if (annot != null && !annot.enabled()) {
return;
}
String name = someLogicToDeriveName();
AnnotationConfig config = someLogicToDeriveConfig();
try (var myBeanHandle = Arc.container().instance(MyBean.class)) {
MyBean myBean = myBeanHandle.get();
context.register(new MyFilter(myBean, config, name));
}
}
}
The bean it is accessing has a runtime config dependency.
Exception when building the Quarkus app:
2023-03-14 20:00:14,516 ERROR [io.qua.run.boo.StartupActionImpl] (Quarkus Main Thread) Error running Quarkus: java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:119)
at java.base/java.lang.reflect.Method.invoke(Method.java:578)
at io.quarkus.runner.bootstrap.StartupActionImpl$1.run(StartupActionImpl.java:104)
at java.base/java.lang.Thread.run(Thread.java:1589)
Caused by: java.lang.ExceptionInInitializerError
at java.base/jdk.internal.misc.Unsafe.ensureClassInitialized0(Native Method)
at java.base/jdk.internal.misc.Unsafe.ensureClassInitialized(Unsafe.java:1160)
at java.base/jdk.internal.reflect.MethodHandleAccessorFactory.ensureClassInitialized(MethodHandleAccessorFactory.java:300)
at java.base/jdk.internal.reflect.MethodHandleAccessorFactory.newConstructorAccessor(MethodHandleAccessorFactory.java:103)
at java.base/jdk.internal.reflect.ReflectionFactory.newConstructorAccessor(ReflectionFactory.java:201)
at java.base/java.lang.reflect.Constructor.acquireConstructorAccessor(Constructor.java:547)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:497)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:484)
at io.quarkus.runtime.Quarkus.run(Quarkus.java:70)
at io.quarkus.runtime.Quarkus.run(Quarkus.java:44)
at io.quarkus.runtime.Quarkus.run(Quarkus.java:124)
at io.quarkus.runner.GeneratedMain.main(Unknown Source)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
... 3 more
Caused by: java.lang.RuntimeException: Failed to start quarkus
at io.quarkus.runner.ApplicationImpl.<clinit>(Unknown Source)
... 16 more
Caused by: javax.enterprise.inject.CreationException: Config root [com.{snip}.quarkus.{snip}.extension.config.MyConfigSource] with config phase [RUN_TIME] not initialized yet.
I've tried to remove the @Provider
annotation and expose it as a CDI bean from my extension instead, but then it never actually ends up registering itself as a filter. Is there a programmatic way to do so, or is there an idiomatic way to inject a runtime bean (with runtime config dependencies) into a DynamicFeature annotated with @Provider
?