diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/BothBlockingAndNonBlockingOnApplicationTest.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/BothBlockingAndNonBlockingOnApplicationTest.java new file mode 100644 index 0000000000000..dffe8aca18275 --- /dev/null +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/BothBlockingAndNonBlockingOnApplicationTest.java @@ -0,0 +1,53 @@ +package io.quarkus.resteasy.reactive.server.test; + +import static org.junit.jupiter.api.Assertions.fail; + +import java.util.function.Supplier; + +import javax.enterprise.inject.spi.DeploymentException; +import javax.ws.rs.ApplicationPath; +import javax.ws.rs.Path; +import javax.ws.rs.core.Application; + +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.spec.JavaArchive; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.test.QuarkusUnitTest; +import io.smallrye.common.annotation.Blocking; +import io.smallrye.common.annotation.NonBlocking; + +public class BothBlockingAndNonBlockingOnApplicationTest { + + @RegisterExtension + static QuarkusUnitTest test = new QuarkusUnitTest() + .setArchiveProducer(new Supplier<>() { + @Override + public JavaArchive get() { + return ShrinkWrap.create(JavaArchive.class) + .addClasses(Resource.class, MyApplication.class); + } + }).setExpectedException(DeploymentException.class); + + @Test + public void test() { + fail("Should never have been called"); + } + + @Path("test") + public static class Resource { + + @Path("hello") + public String hello() { + return "hello"; + } + } + + @ApplicationPath("/app") + @Blocking + @NonBlocking + public static class MyApplication extends Application { + } + +} diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/BothBlockingAndNonBlockingOnClassTest.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/BothBlockingAndNonBlockingOnClassTest.java new file mode 100644 index 0000000000000..dafd14a08adae --- /dev/null +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/BothBlockingAndNonBlockingOnClassTest.java @@ -0,0 +1,46 @@ +package io.quarkus.resteasy.reactive.server.test; + +import static org.junit.jupiter.api.Assertions.fail; + +import java.util.function.Supplier; + +import javax.enterprise.inject.spi.DeploymentException; +import javax.ws.rs.Path; + +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.spec.JavaArchive; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.test.QuarkusUnitTest; +import io.smallrye.common.annotation.Blocking; +import io.smallrye.common.annotation.NonBlocking; + +public class BothBlockingAndNonBlockingOnClassTest { + + @RegisterExtension + static QuarkusUnitTest test = new QuarkusUnitTest() + .setArchiveProducer(new Supplier<>() { + @Override + public JavaArchive get() { + return ShrinkWrap.create(JavaArchive.class) + .addClasses(Resource.class); + } + }).setExpectedException(DeploymentException.class); + + @Test + public void test() { + fail("Should never have been called"); + } + + @Path("test") + @Blocking + @NonBlocking + public static class Resource { + + @Path("hello") + public String hello() { + return "hello"; + } + } +} diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/BothBlockingAndNonBlockingOnMethodTest.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/BothBlockingAndNonBlockingOnMethodTest.java new file mode 100644 index 0000000000000..0cb2def5be083 --- /dev/null +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/BothBlockingAndNonBlockingOnMethodTest.java @@ -0,0 +1,46 @@ +package io.quarkus.resteasy.reactive.server.test; + +import static org.junit.jupiter.api.Assertions.fail; + +import java.util.function.Supplier; + +import javax.enterprise.inject.spi.DeploymentException; +import javax.ws.rs.Path; + +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.spec.JavaArchive; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.test.QuarkusUnitTest; +import io.smallrye.common.annotation.Blocking; +import io.smallrye.common.annotation.NonBlocking; + +public class BothBlockingAndNonBlockingOnMethodTest { + + @RegisterExtension + static QuarkusUnitTest test = new QuarkusUnitTest() + .setArchiveProducer(new Supplier<>() { + @Override + public JavaArchive get() { + return ShrinkWrap.create(JavaArchive.class) + .addClasses(Resource.class); + } + }).setExpectedException(DeploymentException.class); + + @Test + public void test() { + fail("Should never have been called"); + } + + @Path("test") + public static class Resource { + + @Path("hello") + @Blocking + @NonBlocking + public String hello() { + return "hello"; + } + } +} diff --git a/independent-projects/resteasy-reactive/common/processor/src/main/java/org/jboss/resteasy/reactive/common/processor/EndpointIndexer.java b/independent-projects/resteasy-reactive/common/processor/src/main/java/org/jboss/resteasy/reactive/common/processor/EndpointIndexer.java index c09283af77e5b..194aef4ac72de 100644 --- a/independent-projects/resteasy-reactive/common/processor/src/main/java/org/jboss/resteasy/reactive/common/processor/EndpointIndexer.java +++ b/independent-projects/resteasy-reactive/common/processor/src/main/java/org/jboss/resteasy/reactive/common/processor/EndpointIndexer.java @@ -561,6 +561,15 @@ private boolean isBlocking(MethodInfo info, BlockingDefault defaultValue) { Map.Entry<AnnotationTarget, AnnotationInstance> nonBlockingAnnotation = getInheritableAnnotation(info, NON_BLOCKING); if ((blockingAnnotation != null) && (nonBlockingAnnotation != null)) { + if (blockingAnnotation.getKey().kind() == nonBlockingAnnotation.getKey().kind()) { + if (blockingAnnotation.getKey().kind() == AnnotationTarget.Kind.METHOD) { + throw new DeploymentException("Method '" + info.name() + "' of class '" + info.declaringClass().name() + + "' contains both @Blocking and @NonBlocking annotations."); + } else { + throw new DeploymentException("Class '" + info.declaringClass().name() + + "' contains both @Blocking and @NonBlocking annotations."); + } + } if (blockingAnnotation.getKey().kind() == AnnotationTarget.Kind.METHOD) { // the most specific annotation was the @Blocking annotation on the method return true; diff --git a/independent-projects/resteasy-reactive/common/processor/src/main/java/org/jboss/resteasy/reactive/common/processor/scanning/ResteasyReactiveScanner.java b/independent-projects/resteasy-reactive/common/processor/src/main/java/org/jboss/resteasy/reactive/common/processor/scanning/ResteasyReactiveScanner.java index a2a9020bc68bb..5464cc8dfbf07 100644 --- a/independent-projects/resteasy-reactive/common/processor/src/main/java/org/jboss/resteasy/reactive/common/processor/scanning/ResteasyReactiveScanner.java +++ b/independent-projects/resteasy-reactive/common/processor/src/main/java/org/jboss/resteasy/reactive/common/processor/scanning/ResteasyReactiveScanner.java @@ -20,6 +20,7 @@ import java.util.Map; import java.util.Set; import java.util.stream.Collectors; +import javax.enterprise.inject.spi.DeploymentException; import javax.ws.rs.core.Application; import org.jboss.jandex.AnnotationInstance; import org.jboss.jandex.AnnotationTarget; @@ -95,6 +96,10 @@ public static ApplicationScanningResult scanForApplicationClass(IndexView index, throw new RuntimeException("Unable to handle class: " + applicationClass, e); } if (applicationClassInfo.classAnnotation(ResteasyReactiveDotNames.BLOCKING) != null) { + if (applicationClassInfo.classAnnotation(ResteasyReactiveDotNames.NON_BLOCKING) != null) { + throw new DeploymentException("JAX-RS Application class '" + applicationClassInfo.name() + + "' contains both @Blocking and @NonBlocking annotations."); + } blocking = BlockingDefault.BLOCKING; } else if (applicationClassInfo.classAnnotation(ResteasyReactiveDotNames.NON_BLOCKING) != null) { blocking = BlockingDefault.NON_BLOCKING;