diff --git a/microprofile/fault-tolerance/pom.xml b/microprofile/fault-tolerance/pom.xml
index 797eba92d9a..17d3eae60ba 100644
--- a/microprofile/fault-tolerance/pom.xml
+++ b/microprofile/fault-tolerance/pom.xml
@@ -123,6 +123,11 @@
helidon-microprofile-testing-junit5
test
+
+ org.mockito
+ mockito-core
+ test
+
diff --git a/microprofile/fault-tolerance/src/main/java/io/helidon/microprofile/faulttolerance/FaultToleranceExtension.java b/microprofile/fault-tolerance/src/main/java/io/helidon/microprofile/faulttolerance/FaultToleranceExtension.java
index 80945de55b6..7c551c79e26 100644
--- a/microprofile/fault-tolerance/src/main/java/io/helidon/microprofile/faulttolerance/FaultToleranceExtension.java
+++ b/microprofile/fault-tolerance/src/main/java/io/helidon/microprofile/faulttolerance/FaultToleranceExtension.java
@@ -17,12 +17,14 @@
package io.helidon.microprofile.faulttolerance;
import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;
import jakarta.annotation.Priority;
@@ -33,6 +35,7 @@
import jakarta.enterprise.inject.spi.AnnotatedField;
import jakarta.enterprise.inject.spi.AnnotatedMethod;
import jakarta.enterprise.inject.spi.AnnotatedType;
+import jakarta.enterprise.inject.spi.Bean;
import jakarta.enterprise.inject.spi.BeanManager;
import jakarta.enterprise.inject.spi.BeforeBeanDiscovery;
import jakarta.enterprise.inject.spi.BeforeShutdown;
@@ -50,6 +53,7 @@
import org.eclipse.microprofile.faulttolerance.Fallback;
import org.eclipse.microprofile.faulttolerance.Retry;
import org.eclipse.microprofile.faulttolerance.Timeout;
+import org.eclipse.microprofile.faulttolerance.exceptions.FaultToleranceDefinitionException;
import org.glassfish.jersey.process.internal.RequestScope;
import static jakarta.interceptor.Interceptor.Priority.LIBRARY_BEFORE;
@@ -210,8 +214,6 @@ void validateAnnotations(BeanManager bm,
@Initialized(ApplicationScoped.class) Object event) {
if (FaultToleranceMetrics.enabled()) {
getRegisteredMethods().forEach(annotatedMethod -> {
- final AnnotatedType> annotatedType = annotatedMethod.getDeclaringType();
-
// Metrics depending on the annotationSet present
if (MethodAntn.isAnnotationPresent(annotatedMethod, Retry.class, bm)) {
new RetryAntn(annotatedMethod).validate();
@@ -230,11 +232,25 @@ void validateAnnotations(BeanManager bm,
}
if (MethodAntn.isAnnotationPresent(annotatedMethod, Asynchronous.class, bm)) {
new AsynchronousAntn(annotatedMethod).validate();
+ validateWithExecutor(bm, annotatedMethod.getJavaMember());
}
});
}
}
+ static void validateWithExecutor(BeanManager bm, Method method) {
+ WithExecutor withExecutor = method.getAnnotation(WithExecutor.class);
+ if (withExecutor != null) {
+ Set> beans = bm.getBeans(ExecutorService.class, withExecutor);
+ if (beans.isEmpty()) {
+ throw new FaultToleranceDefinitionException("Unable to resolved named executor service '"
+ + withExecutor.value() + "' at "
+ + method.getDeclaringClass().getName() + "::"
+ + method.getName());
+ }
+ }
+ }
+
void close(@Observes BeforeShutdown shutdown) {
FaultToleranceMetrics.close();
// we need to clear method cache, as the next start could use different config
diff --git a/microprofile/fault-tolerance/src/main/java/io/helidon/microprofile/faulttolerance/MethodAntn.java b/microprofile/fault-tolerance/src/main/java/io/helidon/microprofile/faulttolerance/MethodAntn.java
index eb564ef0618..67f5e0bf1ee 100644
--- a/microprofile/fault-tolerance/src/main/java/io/helidon/microprofile/faulttolerance/MethodAntn.java
+++ b/microprofile/fault-tolerance/src/main/java/io/helidon/microprofile/faulttolerance/MethodAntn.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, 2023 Oracle and/or its affiliates.
+ * Copyright (c) 2018, 2024 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -39,8 +39,6 @@ abstract class MethodAntn {
private static final AnnotationFinder ANNOTATION_FINDER = AnnotationFinder.create(Retry.class.getPackage());
- private final AnnotatedType> annotatedType;
-
private final AnnotatedMethod> annotatedMethod;
enum MatchingType {
@@ -80,7 +78,6 @@ public A getAnnotation() {
*/
MethodAntn(AnnotatedMethod> annotatedMethod) {
this.annotatedMethod = annotatedMethod;
- this.annotatedType = annotatedMethod.getDeclaringType();
}
Method method() {
diff --git a/microprofile/fault-tolerance/src/main/java/io/helidon/microprofile/faulttolerance/MethodInvoker.java b/microprofile/fault-tolerance/src/main/java/io/helidon/microprofile/faulttolerance/MethodInvoker.java
index bc237ba8012..a6169a0bd1d 100644
--- a/microprofile/fault-tolerance/src/main/java/io/helidon/microprofile/faulttolerance/MethodInvoker.java
+++ b/microprofile/fault-tolerance/src/main/java/io/helidon/microprofile/faulttolerance/MethodInvoker.java
@@ -43,12 +43,10 @@
import io.helidon.faulttolerance.RetryTimeoutException;
import io.helidon.faulttolerance.Timeout;
-import jakarta.enterprise.inject.UnsatisfiedResolutionException;
import jakarta.enterprise.inject.spi.CDI;
import jakarta.interceptor.InvocationContext;
import org.eclipse.microprofile.faulttolerance.exceptions.BulkheadException;
import org.eclipse.microprofile.faulttolerance.exceptions.CircuitBreakerOpenException;
-import org.eclipse.microprofile.faulttolerance.exceptions.FaultToleranceException;
import org.eclipse.microprofile.metrics.Counter;
import static io.helidon.faulttolerance.SupplierHelper.toRuntimeException;
@@ -343,12 +341,8 @@ private CompletableFuture