diff --git a/extensions/amazon-lambda/deployment/src/main/java/io/quarkus/amazon/lambda/deployment/AmazonLambdaProcessor.java b/extensions/amazon-lambda/deployment/src/main/java/io/quarkus/amazon/lambda/deployment/AmazonLambdaProcessor.java index eb990d199fc7f..26ca21e422ef4 100644 --- a/extensions/amazon-lambda/deployment/src/main/java/io/quarkus/amazon/lambda/deployment/AmazonLambdaProcessor.java +++ b/extensions/amazon-lambda/deployment/src/main/java/io/quarkus/amazon/lambda/deployment/AmazonLambdaProcessor.java @@ -114,6 +114,8 @@ List discover(CombinedIndexBuildItem combinedIndexBuildIt final DotName name = info.name(); final String lambda = name.toString(); builder.addBeanClass(lambda); + reflectiveClassBuildItemBuildProducer + .produce(ReflectiveClassBuildItem.builder(lambda).methods().build()); String cdiName = null; AnnotationInstance named = info.declaredAnnotation(NAMED); @@ -148,18 +150,9 @@ List discover(CombinedIndexBuildItem combinedIndexBuildIt } } } - if (!done) { - current = combinedIndexBuildItem.getIndex().getClassByName(current.superName()); - } - } - if (done) { - String handlerClass = current.name().toString(); - ret.add(new AmazonLambdaBuildItem(handlerClass, cdiName, streamHandler)); - reflectiveClassBuildItemBuildProducer.produce(ReflectiveClassBuildItem.builder(handlerClass).methods() - .reason(getClass().getName() - + ": reflectively accessed in io.quarkus.amazon.lambda.runtime.AmazonLambdaRecorder.discoverHandlerMethod") - .build()); + current = combinedIndexBuildItem.getIndex().getClassByName(current.superName()); } + ret.add(new AmazonLambdaBuildItem(lambda, cdiName, streamHandler)); } additionalBeanBuildItemBuildProducer.produce(builder.build()); reflectiveClassBuildItemBuildProducer @@ -256,7 +249,7 @@ public void recordStaticInitHandlerClass(List lambdas, } } else if (lambdas == null || lambdas.isEmpty()) { String errorMessage = "Unable to find handler class, make sure your deployment includes a single " - + RequestHandler.class.getName() + " or, " + RequestStreamHandler.class.getName() + " implementation"; + + RequestHandler.class.getName() + " or " + RequestStreamHandler.class.getName() + " implementation"; throw new RuntimeException(errorMessage); } } diff --git a/extensions/amazon-lambda/deployment/src/test/java/io/quarkus/amazon/lambda/deployment/testing/LambdaWithHierarchyTest.java b/extensions/amazon-lambda/deployment/src/test/java/io/quarkus/amazon/lambda/deployment/testing/LambdaWithHierarchyTest.java new file mode 100644 index 0000000000000..6b99eca848657 --- /dev/null +++ b/extensions/amazon-lambda/deployment/src/test/java/io/quarkus/amazon/lambda/deployment/testing/LambdaWithHierarchyTest.java @@ -0,0 +1,76 @@ +package io.quarkus.amazon.lambda.deployment.testing; + +import static io.restassured.RestAssured.given; +import static org.hamcrest.CoreMatchers.containsString; + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Named; + +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 com.amazonaws.services.lambda.runtime.Context; +import com.amazonaws.services.lambda.runtime.RequestHandler; + +import io.quarkus.test.QuarkusUnitTest; + +class LambdaWithHierarchyTest { + + @RegisterExtension + static final QuarkusUnitTest test = new QuarkusUnitTest().setArchiveProducer(() -> ShrinkWrap + .create(JavaArchive.class) + .addClasses(GreetingLambda.class, AbstractRequestHandler.class, Person.class)); + + // https://github.com/quarkusio/quarkus/issues/49413 + @Test + public void testLambdaWithHierarchy() throws Exception { + // you test your lambdas by invoking on http://localhost:8081 + // this works in dev mode too + + Person in = new Person("dagrammy"); + given() + .contentType("application/json") + .accept("application/json") + .body(in) + .when() + .post() + .then() + .statusCode(200) + .body(containsString("Hello dagrammy")); + } + + @ApplicationScoped + @Named("GreetingLambda") + public static class GreetingLambda extends AbstractRequestHandler { + + public String getName(Person input) { + return "Hello " + input.getName(); + } + + } + + public static class Person { + + private final String name; + + public Person(String name) { + this.name = name; + } + + public String getName() { + return name; + } + } + + public static abstract class AbstractRequestHandler implements RequestHandler { + + @Override + public R handleRequest(T input, Context context) { + return getName(input); + } + + public abstract R getName(T input); + } +} diff --git a/extensions/amazon-lambda/runtime/src/main/java/io/quarkus/amazon/lambda/runtime/AmazonLambdaRecorder.java b/extensions/amazon-lambda/runtime/src/main/java/io/quarkus/amazon/lambda/runtime/AmazonLambdaRecorder.java index d854f8c062846..6dbf11f2e498e 100644 --- a/extensions/amazon-lambda/runtime/src/main/java/io/quarkus/amazon/lambda/runtime/AmazonLambdaRecorder.java +++ b/extensions/amazon-lambda/runtime/src/main/java/io/quarkus/amazon/lambda/runtime/AmazonLambdaRecorder.java @@ -88,7 +88,7 @@ public static void handle(InputStream inputStream, OutputStream outputStream, Co } private static Method discoverHandlerMethod(Class> handlerClass) { - final Method[] methods = handlerClass.getDeclaredMethods(); + final Method[] methods = handlerClass.getMethods(); Method method = null; for (int i = 0; i < methods.length && method == null; i++) { if (methods[i].getName().equals("handleRequest")) {