Skip to content

Smallrye fault tolerance retry policy goes in StackOverflowError #47422

@joystuffs

Description

@joystuffs

Describe the bug

Hi,

I noticed an unexpected behavior after updating Smallrye fault tolerance

from

 io.quarkus:quarkus-smallrye-fault-tolerance:3.15.3
 io.smallrye:smallrye-fault-tolerance:6.4.0

to

io.quarkus:quarkus-smallrye-fault-tolerance:3.20.0
io.smallrye:smallrye-fault-tolerance:6.9.0

Out of nowhere, I started getting a StackOverflowError, something that never happened in the previous version.

  
java.util.concurrent.CompletionException: java.lang.StackOverflowError at
java.base/java.util.concurrent.CompletableFuture.encodeThrowable(Unknown Source) at
java.base/java.util.concurrent.CompletableFuture.completeThrowable(Unknown Source) at
java.base/java.util.concurrent.CompletableFuture.uniWhenComplete(Unknown Source) at
java.base/java.util.concurrent.CompletableFuture.uniWhenCompleteStage(Unknown Source) at
java.base/java.util.concurrent.CompletableFuture.whenComplete(Unknown Source) 	at
java.base/java.util.concurrent.CompletableFuture$MinimalStage.whenComplete(Unknown Source) at
io.quarkus.scheduler.common.runtime.DefaultInvoker.invoke(DefaultInvoker.java:25) at
io.quarkus.scheduler.common.runtime.DelegateInvoker.invokeDelegate(DelegateInvoker.java:29) at
io.quarkus.scheduler.common.runtime.StatusEmitterInvoker.invoke(StatusEmitterInvoker.java:35) at
io.quarkus.scheduler.common.runtime.DelegateInvoker.invokeDelegate(DelegateInvoker.java:29) at
io.quarkus.scheduler.common.runtime.DelegateInvoker.invokeComplete(DelegateInvoker.java:36) at
io.quarkus.scheduler.common.runtime.OffloadingInvoker$2.call(OffloadingInvoker.java:54) at
io.quarkus.scheduler.common.runtime.OffloadingInvoker$2.call(OffloadingInvoker.java:51) at
io.vertx.core.impl.ContextImpl.lambda$executeBlocking$4(ContextImpl.java:192) at
io.vertx.core.impl.ContextInternal.dispatch(ContextInternal.java:270) at
io.vertx.core.impl.ContextImpl$1.execute(ContextImpl.java:221) at
io.vertx.core.impl.WorkerTask.run(WorkerTask.java:56) at
io.quarkus.vertx.core.runtime.VertxCoreRecorder$15.runWith(VertxCoreRecorder.java:643) 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(Unknown Source)
  

below the programmatically TypedGuard used for the retries.

I followed the official update guide to rewrite the retry policy, even though the actual code change was minimal.

ref : https://smallrye.io/docs/smallrye-fault-tolerance/6.9.0/reference/programmatic-api.html

TypedGuard.create(Response.class)
                .withDescription("retry policy")
                .withRetry()
                .maxDuration(30, ChronoUnit.SECONDS)
                .maxRetries(-1)
                .abortOn(DomainException.class)
                .retryOn(List.of(DomainRetryableException.class))
                .done()
                .withTimeout()
                .duration(10, ChronoUnit.SECONDS)
                .done()
                .build();

maybe there is a new config , I'm missing.

any clue of the stackOverFlow?

Expected behavior

have the same behavior as in the previous version

Actual behavior

Out of nowhere, I started getting a StackOverflowError, something that never happened in the previous version.

How to Reproduce?

below the TypedGuard used for the retry

TypedGuard.create(Response.class)
                .withDescription("retry policy")
                .withRetry()
                .maxDuration(30, ChronoUnit.SECONDS)
                .maxRetries(-1)
                .abortOn(DomainException.class)
                .retryOn(List.of(DomainRetryableException.class))
                .done()
                .withTimeout()
                .duration(10, ChronoUnit.SECONDS)
                .done()
                .build();

Output of uname -a or ver

No response

Output of java -version

21

Quarkus version or git rev

3.20.0

Build tool (ie. output of mvnw --version or gradlew --version)

No response

Additional information

No response

Metadata

Metadata

Assignees

Type

No type

Projects

Status

3.20.3

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions