-
Notifications
You must be signed in to change notification settings - Fork 3k
Description
Describe the bug
Since Quarkus 3.21.3, REST client interfaces fails to initialize if they have any methods with a @BeanParam
annotated parameter that returns a sub-resource interface. The following exception is thrown:
java.lang.RuntimeException: Error injecting org.acme.subresourcebean.TestClient org.acme.subresourcebean.TestResource.client
at org.acme.subresourcebean.TestResource_Bean.doCreate(Unknown Source)
at org.acme.subresourcebean.TestResource_Bean.create(Unknown Source)
at org.acme.subresourcebean.TestResource_Bean.create(Unknown Source)
at io.quarkus.arc.impl.AbstractSharedContext.createInstanceHandle(AbstractSharedContext.java:119)
at io.quarkus.arc.impl.AbstractSharedContext$1.get(AbstractSharedContext.java:38)
at io.quarkus.arc.impl.AbstractSharedContext$1.get(AbstractSharedContext.java:35)
at io.quarkus.arc.impl.LazyValue.get(LazyValue.java:32)
at io.quarkus.arc.impl.ComputingCache.computeIfAbsent(ComputingCache.java:69)
at io.quarkus.arc.impl.ComputingCacheContextInstances.computeIfAbsent(ComputingCacheContextInstances.java:19)
at io.quarkus.arc.impl.AbstractSharedContext.get(AbstractSharedContext.java:35)
at org.acme.subresourcebean.TestResource_Bean.get(Unknown Source)
at org.acme.subresourcebean.TestResource_Bean.get(Unknown Source)
at io.quarkus.arc.impl.ArcContainerImpl.beanInstanceHandle(ArcContainerImpl.java:570)
at io.quarkus.arc.impl.ArcContainerImpl.beanInstanceHandle(ArcContainerImpl.java:550)
at io.quarkus.arc.impl.ArcContainerImpl.beanInstanceHandle(ArcContainerImpl.java:583)
at io.quarkus.arc.impl.ArcContainerImpl$3.get(ArcContainerImpl.java:337)
at io.quarkus.arc.impl.ArcContainerImpl$3.get(ArcContainerImpl.java:334)
at io.quarkus.arc.runtime.BeanContainerImpl$1.create(BeanContainerImpl.java:62)
at io.quarkus.resteasy.reactive.common.runtime.ArcBeanFactory.createInstance(ArcBeanFactory.java:27)
at org.jboss.resteasy.reactive.server.handlers.InstanceHandler.handle(InstanceHandler.java:26)
at io.quarkus.resteasy.reactive.server.runtime.QuarkusResteasyReactiveRequestContext.invokeHandler(QuarkusResteasyReactiveRequestContext.java:139)
at org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext.run(AbstractResteasyReactiveContext.java:147)
at io.quarkus.vertx.core.runtime.VertxCoreRecorder$15.runWith(VertxCoreRecorder.java:638)
at org.jboss.threads.EnhancedQueueExecutor$Task.doRunWith(EnhancedQueueExecutor.java:2675)
at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2654)
at org.jboss.threads.EnhancedQueueExecutor.runThreadBody(EnhancedQueueExecutor.java:1627)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1594)
at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:11)
at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:11)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:840)
Caused by: org.eclipse.microprofile.rest.client.RestClientDefinitionException: org.jboss.resteasy.reactive.client.api.InvalidRestClientDefinitionException: Failed to generate client for class interface org.acme.subresourcebean.TestClient : Must be a Class or String, got null
at io.quarkus.rest.client.reactive.runtime.RestClientBuilderImpl.build(RestClientBuilderImpl.java:595)
at io.quarkus.rest.client.reactive.runtime.QuarkusRestClientBuilderImpl.build(QuarkusRestClientBuilderImpl.java:279)
at io.quarkus.rest.client.reactive.runtime.RestClientCDIDelegateBuilder.build(RestClientCDIDelegateBuilder.java:74)
at io.quarkus.rest.client.reactive.runtime.RestClientCDIDelegateBuilder.createDelegate(RestClientCDIDelegateBuilder.java:54)
at io.quarkus.rest.client.reactive.runtime.RestClientReactiveCDIWrapperBase.delegate(RestClientReactiveCDIWrapperBase.java:76)
at io.quarkus.rest.client.reactive.runtime.RestClientReactiveCDIWrapperBase.<init>(RestClientReactiveCDIWrapperBase.java:30)
at org.acme.subresourcebean.TestClient$$CDIWrapper.<init>(Unknown Source)
at org.acme.subresourcebean.TestClient$$CDIWrapper_ClientProxy.<init>(Unknown Source)
at org.acme.subresourcebean.TestClient$$CDIWrapper_Bean.proxy(Unknown Source)
... 31 more
Caused by: org.jboss.resteasy.reactive.client.api.InvalidRestClientDefinitionException: Failed to generate client for class interface org.acme.subresourcebean.TestClient : Must be a Class or String, got null
at org.jboss.resteasy.reactive.client.impl.ClientProxies.get(ClientProxies.java:31)
at org.jboss.resteasy.reactive.client.impl.WebTargetImpl.proxy(WebTargetImpl.java:465)
at io.quarkus.rest.client.reactive.runtime.RestClientBuilderImpl.build(RestClientBuilderImpl.java:593)
... 41 more
The cause of this exception happens at build time, but does not cause a build failure:
2025-05-12 09:14:21,323 DEBUG [io.qua.jax.cli.rea.dep.JaxrsClientReactiveProcessor] (build-10) Failed to create client proxy for org.acme.subresourcebean.TestClient this can usually be safely ignored: java.lang.IllegalArgumentException: Must be a Class or String, got null
at io.quarkus.gizmo.DescriptorUtils.objectToDescriptor(DescriptorUtils.java:133)
at io.quarkus.gizmo.FieldDescriptor.of(FieldDescriptor.java:44)
at io.quarkus.gizmo.ClassCreator.getFieldCreator(ClassCreator.java:126)
at io.quarkus.jaxrs.client.reactive.deployment.JaxrsClientReactiveProcessor.handleSubResourceMethod(JaxrsClientReactiveProcessor.java:1551)
at io.quarkus.jaxrs.client.reactive.deployment.JaxrsClientReactiveProcessor.generateClientInvoker(JaxrsClientReactiveProcessor.java:932)
at io.quarkus.jaxrs.client.reactive.deployment.JaxrsClientReactiveProcessor.setupClientProxies(JaxrsClientReactiveProcessor.java:423)
at java.base/java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:732)
at io.quarkus.deployment.ExtensionLoader$3.execute(ExtensionLoader.java:856)
at io.quarkus.builder.BuildContext.run(BuildContext.java:255)
at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18)
at org.jboss.threads.EnhancedQueueExecutor$Task.doRunWith(EnhancedQueueExecutor.java:2675)
at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2654)
at org.jboss.threads.EnhancedQueueExecutor.runThreadBody(EnhancedQueueExecutor.java:1627)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1594)
at java.base/java.lang.Thread.run(Thread.java:840)
at org.jboss.threads.JBossThread.run(JBossThread.java:499)
This used to work, but has failed since Quarkus version 3.21.3.
The most likely cause Is the changes introduced in #47368, specifically changing param.type
to param.declaredType
in the JaxrsClientReactiveProcessor#handleSubResourceMethod
method.
Looking at this with a debugger, I can see that the declaredType
field on the FieldDescriptor
object is null
, whereas the type
field contains the correct class name.
Expected behavior
No response
Actual behavior
No response
How to Reproduce?
I've created a GitHub repository that reproduces this problem: https://github.com/jburkal/quarkus-beanparam-test
Specifically:
- Client: https://github.com/jburkal/quarkus-beanparam-test/blob/main/src/main/java/org/acme/subresourcebean/TestClient.java
- Sub-resource: https://github.com/jburkal/quarkus-beanparam-test/blob/main/src/main/java/org/acme/subresourcebean/SubClient.java
- Bean parameter: https://github.com/jburkal/quarkus-beanparam-test/blob/main/src/main/java/org/acme/TestBean.java
Output of uname -a
or ver
No response
Output of java -version
No response
Quarkus version or git rev
3.21.3
Build tool (ie. output of mvnw --version
or gradlew --version
)
No response
Additional information
No response