Repository navigation
@Blocking is required when using oauth2 #923
Copy link
Copy link
Description
Context
When using oauth2 in a workflow:
@ApplicationScoped
public class ProcessPhotoFlow extends Flow {
@ConfigProperty(name = "photoService.authority")
String authority;
@ConfigProperty(name = "photoService.baseUrl")
String baseUrl;
@Override
public Workflow descriptor() {
return FlowWorkflowBuilder.workflow("processPhotoWorkflow", "guru-quarkus")
.use(u -> u.secrets("photoService"))
.tasks(
http("processPhoto")
.post()
.body("${ . }")
.endpoint(baseUrl + "/api/photos/photoId/process",
oauth2(authority, CLIENT_CREDENTIALS,
"${ $secret.photoService.clientId }",
"${ $secret.photoService.clientSecret }",
e -> e.token("/protocol/openid-connect/token")))
).build();
}
}And trying to execute it in a non-blocking way:
@Path("/photos")
public class PhotoResource {
@Inject
ProcessPhotoFlow processPhotoFlow;
@POST
@Path("/{photoId}/process")
@NonBlocking
public Uni<Response> process(@PathParam("photoId") String photoId) {
return processPhotoFlow.startInstance(Map.of("photoId", photoId))
.onItem().transform(model -> Response.ok(model.asJavaObject()).build());
}
}We got the following stacktrace:
Suppressed: org.jboss.resteasy.reactive.common.core.BlockingNotAllowedException
at org.jboss.resteasy.reactive.client.impl.InvocationBuilderImpl.unwrap(InvocationBuilderImpl.java:199)
at org.jboss.resteasy.reactive.client.impl.InvocationBuilderImpl.post(InvocationBuilderImpl.java:243)
at io.serverlessworkflow.impl.executors.http.auth.JaxRSAccessTokenProvider.executeRequest(JaxRSAccessTokenProvider.java:135)
at io.serverlessworkflow.impl.executors.http.auth.JaxRSAccessTokenProvider.invoke(JaxRSAccessTokenProvider.java:76)
at io.serverlessworkflow.impl.executors.http.auth.JaxRSAccessTokenProvider.validateAndGet(JaxRSAccessTokenProvider.java:60)
at io.serverlessworkflow.impl.auth.CommonOAuthProvider.content(CommonOAuthProvider.java:55)
at io.serverlessworkflow.impl.executors.http.AbstractRequestExecutor.addAuthHeader(AbstractRequestExecutor.java:116)
at io.serverlessworkflow.impl.executors.http.AbstractRequestExecutor.lambda$apply$0(AbstractRequestExecutor.java:56)
at java.base/java.util.Optional.map(Optional.java:260)
at io.serverlessworkflow.impl.executors.http.AbstractRequestExecutor.apply(AbstractRequestExecutor.java:56)
at io.serverlessworkflow.impl.executors.http.HttpExecutor.apply(HttpExecutor.java:76)
at io.quarkiverse.flow.recorders.WorkflowApplicationCreator$1.lambda$build$0(WorkflowApplicationCreator.java:260)
at io.smallrye.faulttolerance.apiimpl.CallableInvoker.proceed(CallableInvoker.java:32)
at io.smallrye.faulttolerance.core.invocation.CompletionStageSupport.toFuture(CompletionStageSupport.java:37)
at io.smallrye.faulttolerance.apiimpl.GuardCommon.lambda$guard$1(GuardCommon.java:79)
at io.smallrye.faulttolerance.core.FaultToleranceContext.call(FaultToleranceContext.java:20)
at io.smallrye.faulttolerance.core.Invocation.apply(Invocation.java:29)
at io.smallrye.faulttolerance.core.async.ThreadOffload.lambda$apply$2(ThreadOffload.java:44)
at io.smallrye.context.impl.wrappers.SlowContextualRunnable.run(SlowContextualRunnable.java:19)
at io.smallrye.faulttolerance.vertx.VertxExecutor.lambda$execute$1(VertxExecutor.java:28)
at io.vertx.core.impl.ContextInternal.dispatch(ContextInternal.java:270)
at io.vertx.core.impl.ContextInternal.dispatch(ContextInternal.java:252)
at io.vertx.core.impl.ContextInternal.lambda$runOnContext$0(ContextInternal.java:50)
at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:173)
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:166)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:472)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:569)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:1007)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:1474)Workaround
Add @Blocking annotation to the process() method.
Expected behavior
Execute the workflow in a non-blocking way without error.
Own investigation
The problem lives on sdk-java side, the OAuth2 access-token request performed by JaxRSAccessTokenProvider (line 60) is synchronous, blocking JAX-RS client invocation, and unlike the actual workflow HTTP request, it is not offloaded to the workflow'sexecutorService.
Reactions are currently unavailable
Activity
ricardozanini commentedon Sep 2, 2026
It depends on: