diff --git a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/DotNames.java b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/DotNames.java index 4abb701ae574f..3c4909a0b9ffe 100644 --- a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/DotNames.java +++ b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/DotNames.java @@ -46,6 +46,7 @@ import javax.interceptor.AroundInvoke; import javax.interceptor.Interceptor; import javax.interceptor.InterceptorBinding; +import javax.interceptor.InvocationContext; import org.jboss.jandex.ClassInfo; import org.jboss.jandex.DotName; @@ -101,6 +102,7 @@ public final class DotNames { public static final DotName TRANSACTION_PHASE = create(TransactionPhase.class); public static final DotName INITIALIZED = create(Initialized.class); public static final DotName TRANSIENT_REFERENCE = create(TransientReference.class); + public static final DotName INVOCATION_CONTEXT = create(InvocationContext.class); public static final DotName BOOLEAN = create(Boolean.class); public static final DotName BYTE = create(Byte.class); diff --git a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/InterceptorGenerator.java b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/InterceptorGenerator.java index c26b3f64ceb37..a26da991c5894 100644 --- a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/InterceptorGenerator.java +++ b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/InterceptorGenerator.java @@ -223,10 +223,9 @@ private void addIntercept(MethodCreator intercept, MethodInfo interceptorMethod, Class retType = null; if (InterceptionType.AROUND_INVOKE.equals(interceptionType)) { retType = Object.class; - } else if (InterceptionType.AROUND_CONSTRUCT.equals(interceptionType)) { - retType = interceptorMethod.returnType().kind().equals(Type.Kind.VOID) ? void.class : Object.class; } else { - retType = void.class; + // @PostConstruct, @PreDestroy, @AroundConstruct + retType = interceptorMethod.returnType().kind().equals(Type.Kind.VOID) ? void.class : Object.class; } ResultHandle ret; if (Modifier.isPrivate(interceptorMethod.flags())) { diff --git a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/InterceptorInfo.java b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/InterceptorInfo.java index 726b79e5ccc63..a4f62c25d5147 100644 --- a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/InterceptorInfo.java +++ b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/InterceptorInfo.java @@ -64,28 +64,16 @@ public class InterceptorInfo extends BeanInfo implements Comparable parameters = method.parameters(); + if (parameters.size() != 1 || !parameters.get(0).name().equals(DotNames.INVOCATION_CONTEXT)) { + throw new IllegalStateException( + "An interceptor method must accept exactly one parameter of type javax.interceptor.InvocationContext: " + + method + " declared on " + method.declaringClass()); + } + if (!method.returnType().kind().equals(Type.Kind.VOID) && + !method.returnType().name().equals(DotNames.OBJECT)) { + throw new IllegalStateException( + "The return type of an interceptor method must be java.lang.Object or void: " + + method + " declared on " + method.declaringClass()); + } + return method; + } + public Set getBindings() { return bindings; } diff --git a/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/interceptors/mixed/BusinessLifecycleInterceptorTest.java b/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/interceptors/mixed/BusinessLifecycleInterceptorTest.java new file mode 100644 index 0000000000000..18ff3718cfeb5 --- /dev/null +++ b/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/interceptors/mixed/BusinessLifecycleInterceptorTest.java @@ -0,0 +1,59 @@ +package io.quarkus.arc.test.interceptors.mixed; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import io.quarkus.arc.Arc; +import io.quarkus.arc.InstanceHandle; +import io.quarkus.arc.test.ArcTestContainer; +import java.util.concurrent.atomic.AtomicInteger; +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import javax.annotation.Priority; +import javax.enterprise.context.Dependent; +import javax.interceptor.AroundInvoke; +import javax.interceptor.Interceptor; +import javax.interceptor.InvocationContext; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +public class BusinessLifecycleInterceptorTest { + + @RegisterExtension + public ArcTestContainer container = new ArcTestContainer(MyTransactional.class, SimpleBean.class, + SimpleInterceptor.class); + + public static final AtomicInteger INTERCEPTORS_CALLED = new AtomicInteger(); + + @Test + public void testInterception() { + InstanceHandle instance = Arc.container().instance(SimpleBean.class); + SimpleBean simpleBean = instance.get(); + assertEquals(1, INTERCEPTORS_CALLED.get()); + assertEquals(2, simpleBean.ping()); + assertEquals(2, INTERCEPTORS_CALLED.get()); + } + + @Dependent + @MyTransactional + static class SimpleBean { + + int ping() { + return 0; + } + + } + + @Priority(1) + @MyTransactional + @Interceptor + public static class SimpleInterceptor { + + @PostConstruct + @PreDestroy + @AroundInvoke + Object intercept(InvocationContext ctx) throws Exception { + return INTERCEPTORS_CALLED.incrementAndGet(); + } + + } +} diff --git a/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/interceptors/mixed/MyTransactional.java b/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/interceptors/mixed/MyTransactional.java new file mode 100644 index 0000000000000..5533bf2ad6fb9 --- /dev/null +++ b/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/interceptors/mixed/MyTransactional.java @@ -0,0 +1,16 @@ +package io.quarkus.arc.test.interceptors.mixed; + +import static java.lang.annotation.ElementType.CONSTRUCTOR; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; +import javax.interceptor.InterceptorBinding; + +@Target({ TYPE, CONSTRUCTOR }) +@Retention(RUNTIME) +@InterceptorBinding +public @interface MyTransactional { + +}