From 886b8dab2844cdd4882f95417faba8d216e8a5c5 Mon Sep 17 00:00:00 2001 From: Auri Munoz Date: Fri, 22 Nov 2024 13:49:46 +0100 Subject: [PATCH] Don't ignore Spring Rest controllers interfaces if contains errors Related to #43704 --- ...ableSpringRestControllerInterfaceTest.java | 48 +++++++++++++++++++ .../common/processor/EndpointIndexer.java | 17 +++++-- 2 files changed, 60 insertions(+), 5 deletions(-) create mode 100644 extensions/spring-web/resteasy-reactive/tests/src/test/java/io/quarkus/spring/web/test/UnbuildableSpringRestControllerInterfaceTest.java diff --git a/extensions/spring-web/resteasy-reactive/tests/src/test/java/io/quarkus/spring/web/test/UnbuildableSpringRestControllerInterfaceTest.java b/extensions/spring-web/resteasy-reactive/tests/src/test/java/io/quarkus/spring/web/test/UnbuildableSpringRestControllerInterfaceTest.java new file mode 100644 index 0000000000000..bed1ea5d99976 --- /dev/null +++ b/extensions/spring-web/resteasy-reactive/tests/src/test/java/io/quarkus/spring/web/test/UnbuildableSpringRestControllerInterfaceTest.java @@ -0,0 +1,48 @@ +package io.quarkus.spring.web.test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; + +import jakarta.ws.rs.QueryParam; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import io.quarkus.test.QuarkusProdModeTest; + +public class UnbuildableSpringRestControllerInterfaceTest { + + @RegisterExtension + static final QuarkusProdModeTest config = new QuarkusProdModeTest() + .withApplicationRoot((jar) -> jar + .addClasses(UnbuildableControllerInterface.class)) + .setApplicationName("unbuildable-rest-controller-interface") + .setApplicationVersion("0.1-SNAPSHOT") + .assertBuildException(throwable -> { + assertThat(throwable).isInstanceOf(RuntimeException.class); + assertThat(throwable).hasMessageContaining( + "Cannot have more than one of @PathParam, @QueryParam, @HeaderParam, @FormParam, @CookieParam, @BeanParam, @Context on method"); + }); + + @Test + public void testBuildLogs() { + fail("Should not be called"); + } + + @RestController + @RequestMapping("/unbuildable") + public interface UnbuildableControllerInterface { + @GetMapping("/ping") + String ping(); + + @PostMapping("/hello") + String hello(@RequestParam(required = false) @QueryParam("dung") String params); + + } + +} 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 25633cdd60993..7c322df27abbe 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 @@ -324,16 +324,23 @@ public Optional createEndpoints(ClassInfo classInfo, boolean cons return Optional.of(clazz); } catch (Exception e) { - if (Modifier.isInterface(classInfo.flags()) || Modifier.isAbstract(classInfo.flags())) { - //kinda bogus, but we just ignore failed interfaces for now - //they can have methods that are not valid until they are actually extended by a concrete type - log.debug("Ignoring interface " + classInfo.name(), e); - return Optional.empty(); + if (!isSpringRestController(classInfo)) { + if (Modifier.isInterface(classInfo.flags()) || Modifier.isAbstract(classInfo.flags())) { + //kinda bogus, but we just ignore failed interfaces for now + //they can have methods that are not valid until they are actually extended by a concrete type + log.debug("Ignoring interface " + classInfo.name(), e); + return Optional.empty(); + } } throw new RuntimeException(e); } } + private boolean isSpringRestController(ClassInfo classInfo) { + return classInfo + .declaredAnnotation(DotName.createSimple("org.springframework.web.bind.annotation.RestController")) != null; + } + private String sanitizePath(String path) { // this simply replaces the whitespace characters (not part of a path variable) with %20 // TODO: this might have to be more complex, URL encoding maybe?