quarkus-renarde
quarkus-renarde copied to clipboard
Passing both a @BeanParam and @RestPath allowed on endpoints?
Hi,
In Quarkus/Renarde, can I pass in a @BeanParam and a @RestPath? I'm trying to do a call to this endpoint and I'm getting a class cast exception:
@POST
@Path("/accounts/password/change/{userId}")
@RolesAllowed({Application.USER_ROLE})
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response doChangePassword(@BeanParam Account.PasswordChange passChangeForm, @RestPath Long userId) {
I originally had just form being passed in and the URL didn't have the userId on the path.
I wanted to add the userId to the path so I can pass the user. I could modify the password form to pass it, but I thought I should be able to pass multiple params.
Is this allowed?
Error:
2023-03-13 14:13:17,076 ERROR [io.qua.ver.htt.run.QuarkusErrorHandler] (executor-thread-0) HTTP Request to /accounts/password/change/1400 failed, error id: a31d737a-2f85-4735-932b-0e04a084fd78-1: java.lang.ClassCastException: class java.lang.Long cannot be cast to class com.acme.support.site.rest.Account$PasswordChange (java.lang.Long is in module java.base of loader 'bootstrap'; com.acme.support.site.rest.Account$PasswordChange is in unnamed module of loader io.quarkus.bootstrap.runner.RunnerClassLoader @396a51ab)
at com.acme.support.site.rest.Account.__urivarargs$doChangePassword$33b635c8a9baab1fb6da6216187edcf3bb62c1f7(Account.java)
at __RenardeInit$$function$$6.getRoute(Unknown Source)
at io.quarkiverse.renarde.router.Router.findURI(Router.java:152)
at io.quarkiverse.renarde.util.QuteResolvers.findURI(QuteResolvers.java:65)
at io.quarkiverse.renarde.util.QuteResolvers.lambda$configureEngine$1(QuteResolvers.java:47)
at io.smallrye.context.impl.wrappers.SlowContextualFunction.apply(SlowContextualFunction.java:21)
at io.smallrye.mutiny.operators.uni.UniAndCombination$AndSupervisor.computeAndFireTheOutcome(UniAndCombination.java:147)
at io.smallrye.mutiny.operators.uni.UniAndCombination$AndSupervisor.check(UniAndCombination.java:131)
at io.smallrye.mutiny.operators.uni.UniAndCombination$UniHandler.onItem(UniAndCombination.java:221)
at io.smallrye.mutiny.operators.uni.builders.UniCreateFromCompletionStage$CompletionStageUniSubscription.forwardResult(UniCreateFromCompletionStage.java:63)
at io.quarkus.qute.CompletedStage.whenComplete(CompletedStage.java:268)
at io.smallrye.mutiny.operators.uni.builders.UniCreateFromCompletionStage$CompletionStageUniSubscription.forward(UniCreateFromCompletionStage.java:51)
at io.smallrye.mutiny.operators.uni.builders.UniCreateFromCompletionStage.subscribe(UniCreateFromCompletionStage.java:35)
at io.smallrye.mutiny.operators.AbstractUni.subscribe(AbstractUni.java:36)
at io.smallrye.mutiny.operators.uni.UniAndCombination$UniHandler.subscribe(UniAndCombination.java:234)
at io.smallrye.mutiny.operators.uni.UniAndCombination$AndSupervisor.run(UniAndCombination.java:88)
at io.smallrye.mutiny.operators.uni.UniAndCombination$AndSupervisor.access$000(UniAndCombination.java:57)
at io.smallrye.mutiny.operators.uni.UniAndCombination.subscribe(UniAndCombination.java:54)
at io.smallrye.mutiny.operators.AbstractUni.subscribe(AbstractUni.java:36)
at io.smallrye.mutiny.groups.UniSubscribe.withSubscriber(UniSubscribe.java:52)
at io.smallrye.mutiny.groups.UniSubscribe.with(UniSubscribe.java:112)
at io.smallrye.mutiny.operators.uni.UniSubscribeToCompletionStage.subscribe(UniSubscribeToCompletionStage.java:30)
at io.smallrye.mutiny.groups.UniSubscribe.asCompletionStage(UniSubscribe.java:178)
at io.smallrye.mutiny.groups.UniSubscribe.asCompletionStage(UniSubscribe.java:165)
at io.smallrye.mutiny.Uni.subscribeAsCompletionStage(Uni.java:142)
at io.smallrye.mutiny.converters.uni.ToCompletionStage.apply(ToCompletionStage.java:18)
at io.smallrye.mutiny.converters.uni.ToCompletionStage.apply(ToCompletionStage.java:8)
at io.smallrye.mutiny.groups.UniConvert.with(UniConvert.java:33)
at io.smallrye.mutiny.groups.UniConvert.toCompletionStage(UniConvert.java:38)
at io.quarkiverse.renarde.util.QuteResolvers.lambda$configureEngine$2(QuteResolvers.java:48)
at io.quarkus.qute.ValueResolverBuilder$5.apply(ValueResolverBuilder.java:135)
at io.quarkus.qute.ValueResolverBuilder$5.apply(ValueResolverBuilder.java:132)
at io.quarkus.qute.ValueResolverBuilder$ValueResolverImpl.resolve(ValueResolverBuilder.java:179)
at io.quarkus.qute.EvaluatorImpl.resolve(EvaluatorImpl.java:208)
at io.quarkus.qute.EvaluatorImpl.resolveReference(EvaluatorImpl.java:128)
at io.quarkus.qute.EvaluatorImpl.lambda$evaluate$0(EvaluatorImpl.java:80)
at io.quarkus.qute.CompletedStage.thenCompose(CompletedStage.java:232)
at io.quarkus.qute.EvaluatorImpl.evaluate(EvaluatorImpl.java:79)
at io.quarkus.qute.ResolutionContextImpl$ChildResolutionContext.evaluate(ResolutionContextImpl.java:87)
at io.quarkus.qute.Futures.evaluateParams(Futures.java:50)
at io.quarkus.qute.IncludeSectionHelper.resolve(IncludeSectionHelper.java:54)
at io.quarkus.qute.SectionNode.resolve(SectionNode.java:53)
at io.quarkus.qute.SectionNode.resolve(SectionNode.java:58)
at io.quarkus.qute.SectionNode$SectionResolutionContextImpl.execute(SectionNode.java:223)
at io.quarkus.qute.InsertSectionHelper.resolve(InsertSectionHelper.java:20)
at io.quarkus.qute.SectionNode.resolve(SectionNode.java:53)
at io.quarkus.qute.SectionNode.resolve(SectionNode.java:58)
at io.quarkus.qute.SectionNode$SectionResolutionContextImpl.execute(SectionNode.java:223)
at io.quarkus.qute.SectionHelper$SectionResolutionContext.execute(SectionHelper.java:46)
at io.quarkus.qute.Parser$1.resolve(Parser.java:1247)
at io.quarkus.qute.SectionNode.resolve(SectionNode.java:53)
at io.quarkus.qute.IncludeSectionHelper.lambda$resolve$1(IncludeSectionHelper.java:71)
at java.base/java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:863)
at java.base/java.util.concurrent.CompletableFuture.uniWhenCompleteStage(CompletableFuture.java:887)
at java.base/java.util.concurrent.CompletableFuture.whenComplete(CompletableFuture.java:2325)
at java.base/java.util.concurrent.CompletableFuture.whenComplete(CompletableFuture.java:144)
at io.quarkus.qute.IncludeSectionHelper.resolve(IncludeSectionHelper.java:54)
at io.quarkus.qute.SectionNode.resolve(SectionNode.java:53)
at io.quarkus.qute.SectionNode.resolve(SectionNode.java:58)
at io.quarkus.qute.SectionNode$SectionResolutionContextImpl.execute(SectionNode.java:219)
at io.quarkus.qute.SectionHelper$SectionResolutionContext.execute(SectionHelper.java:46)
at io.quarkus.qute.Parser$1.resolve(Parser.java:1247)
at io.quarkus.qute.SectionNode.resolve(SectionNode.java:53)
at io.quarkus.qute.SectionNode.resolve(SectionNode.java:58)
at io.quarkus.qute.TemplateImpl$TemplateInstanceImpl.renderData(TemplateImpl.java:227)
at io.quarkus.qute.TemplateImpl$TemplateInstanceImpl.renderAsyncNoTimeout(TemplateImpl.java:218)
at io.smallrye.context.impl.wrappers.SlowContextualSupplier.get(SlowContextualSupplier.java:21)
at io.smallrye.mutiny.operators.uni.builders.UniCreateFromCompletionStage.subscribe(UniCreateFromCompletionStage.java:24)
at io.smallrye.mutiny.operators.AbstractUni.subscribe(AbstractUni.java:36)
at io.smallrye.mutiny.operators.uni.UniFailOnTimeout.subscribe(UniFailOnTimeout.java:36)
at io.smallrye.mutiny.operators.AbstractUni.subscribe(AbstractUni.java:36)
at io.smallrye.mutiny.operators.uni.UniOnItemTransformToUni.subscribe(UniOnItemTransformToUni.java:25)
at io.smallrye.mutiny.operators.AbstractUni.subscribe(AbstractUni.java:36)
at io.smallrye.mutiny.groups.UniSubscribe.withSubscriber(UniSubscribe.java:52)
at io.smallrye.mutiny.groups.UniSubscribe.with(UniSubscribe.java:112)
at io.smallrye.mutiny.groups.UniSubscribe.with(UniSubscribe.java:89)
at org.jboss.resteasy.reactive.server.filters.FilterUtil.handleUniVoid(FilterUtil.java:61)
at io.quarkus.resteasy.reactive.qute.runtime.TemplateResponseFilter$GeneratedServerResponseFilter$filter.filter(Unknown Source)
at org.jboss.resteasy.reactive.server.spi.ResteasyReactiveContainerResponseFilter.filter(ResteasyReactiveContainerResponseFilter.java:10)
at org.jboss.resteasy.reactive.server.handlers.ResourceResponseFilterHandler.handle(ResourceResponseFilterHandler.java:25)
at io.quarkus.resteasy.reactive.server.runtime.QuarkusResteasyReactiveRequestContext.invokeHandler(QuarkusResteasyReactiveRequestContext.java:123)
at org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext.run(AbstractResteasyReactiveContext.java:145)
at io.quarkus.vertx.core.runtime.VertxCoreRecorder$14.runWith(VertxCoreRecorder.java:576)
at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2449)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1478)
at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29)
at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:29)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:833)
Ok, I found my answer in this link, sorry for the noise. https://docs.oracle.com/javaee/7/api/javax/ws/rs/BeanParam.html
I just have to add the path param in the incoming bean form. There can be only one main param when using the @BeanForm annotation apparently.
Well, no, this is a bug in the router. You're allowed to have parameters in the @BeanParam
and outside of it.