Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No public method named handleRequest with appropriate method signature on SpringBootLambdaContainerHandler #770

Open
jeusdi opened this issue Feb 21, 2024 · 12 comments
Assignees
Labels

Comments

@jeusdi
Copy link

jeusdi commented Feb 21, 2024

To help us debug your issue fill in the basic information below using the options provided

Serverless Java Container version: 2.0

Implementations: Spring Boot

Framework version: SpringBoot

Frontend service: HTTP API

Deployment method: Serverless Framework

Scenario

I'm trying to execute my lambda.

Expected behavior

Reach my exposed endpoints

Actual behavior

I'm getting:

No public method named handleRequest with appropriate method signature found on class com.amazonaws.serverless.proxy.spring.SpringBootLambdaContainerHandler

Steps to reproduce

Here my pom.xml related tree dependencies:

\- com.amazonaws.serverless:aws-serverless-java-container-springboot3:jar:2.0.0:compile
[INFO]    +- org.springframework.cloud:spring-cloud-function-serverless-web:jar:4.0.6:compile
[INFO]    \- com.amazonaws.serverless:aws-serverless-java-container-core:jar:2.0.0:compile
[INFO]       +- com.amazonaws:aws-lambda-java-core:jar:1.2.3:compile
[INFO]       +- jakarta.servlet:jakarta.servlet-api:jar:6.0.0:compile
[INFO]       +- jakarta.ws.rs:jakarta.ws.rs-api:jar:3.1.0:compile
[INFO]       +- com.fasterxml.jackson.module:jackson-module-afterburner:jar:2.15.3:compile
[INFO]       \- org.apache.commons:commons-fileupload2-jakarta-servlet6:jar:2.0.0-M2:compile
[INFO]          +- org.apache.commons:commons-fileupload2-core:jar:2.0.0-M2:compile
[INFO]          \- commons-io:commons-io:jar:2.15.1:compil

Full log output

Here my lambda output (`aws logs filter-log-events --log-group-name "/aws/lambda/espaidoc-dev-api")

{
  "events": [
    {
      "logStreamName": "2024/02/21/[$LATEST]a70d67063ade2e352772539d2f3a6f74",
      "timestamp": 1708553587372,
      "message": "START RequestId: f61e24d9-9990-43cf-8b29-789a63584e4e Version: $LATEST",
      "ingestionTime": 1708553588494,
      "eventId": "0"
    },
    {
      "logStreamName": "2024/02/21/[$LATEST]a70d67063ade2e352772539d2f3a6f74",
      "timestamp": 1708553587425,
      "message": "No public method named handleRequest with appropriate method signature found on class com.amazonaws.serverless.proxy.spring.SpringBootLambdaContainerHandler",
      "ingestionTime": 1708553588494,
      "eventId": "1"
    },
    {
      "logStreamName": "2024/02/21/[$LATEST]a70d67063ade2e352772539d2f3a6f74",
      "timestamp": 1708553587478,
      "message": "END RequestId: f61e24d9-9990-43cf-8b29-789a63584e4e",
      "ingestionTime": 1708553588494,
      "eventId": "2"
    },
    {
      "logStreamName": "2024/02/21/[$LATEST]a70d67063ade2e352772539d2f3a6f74",
      "timestamp": 1708553587532,
      "message": "REPORT RequestId: f61e24d9-9990-43cf-8b29-789a63584e4e\tDuration: 84.01 ms\tBilled Duration: 85 ms\tMemory Size: 1024 MB\tMax Memory Used: 1024 MB\t",
      "ingestionTime": 1708553588494,
      "eventId": "3"
    }
  ],
  "searchedLogStreams": [
    {
      "logStreamName": "2024/02/21/[$LATEST]a70d67063ade2e352772539d2f3a6f74",
      "searchedCompletely": true
    }
  ]
}

I also put my entire pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <parent>
      <groupId>me.jeusdi.slab.localstack</groupId>
      <artifactId>espaidoc</artifactId>
      <version>0.0.1-SNAPSHOT</version>
   </parent>
   <groupId>me.jeusdi.slab.localstack</groupId>
   <artifactId>frontoffice</artifactId>
   <version>0.0.1-SNAPSHOT</version>
   <name>frontoffice</name>
   <description>PoC to see how to send and receive messages from AWS SQS</description>
   <properties>
      <java.version>17</java.version>
      <spring-boot-dependencies.version>3.2.2</spring-boot-dependencies.version>
      <spring-cloud-aws.version>3.1.0</spring-cloud-aws.version>
   </properties>
   <dependencyManagement>
      <dependencies>
         <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>${spring-boot-dependencies.version}</version>
            <type>pom</type>
            <scope>import</scope>
         </dependency>
         <dependency>
            <groupId>io.awspring.cloud</groupId>
            <artifactId>spring-cloud-aws-dependencies</artifactId>
            <version>${spring-cloud-aws.version}</version>
            <type>pom</type>
            <scope>import</scope>
         </dependency>
      </dependencies>
   </dependencyManagement>
   <dependencies>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-web</artifactId>
      </dependency>
      <dependency>
         <groupId>io.awspring.cloud</groupId>
         <artifactId>spring-cloud-aws-starter-s3</artifactId>
      </dependency>
      <dependency>
         <groupId>io.awspring.cloud</groupId>
         <artifactId>spring-cloud-aws-starter-sqs</artifactId>
      </dependency>
      <dependency>
         <groupId>me.jeusdi.slab.localstack</groupId>
         <artifactId>domain</artifactId>
         <version>0.0.1-SNAPSHOT</version>
      </dependency>
      <dependency>
         <groupId>me.jeusdi.slab.localstack</groupId>
         <artifactId>application</artifactId>
         <version>0.0.1-SNAPSHOT</version>
      </dependency>
      <dependency>
         <groupId>me.jeusdi.slab.localstack</groupId>
         <artifactId>infrastructure</artifactId>
         <version>0.0.1-SNAPSHOT</version>
      </dependency>
      <dependency>
         <groupId>org.projectlombok</groupId>
         <artifactId>lombok</artifactId>
         <optional>true</optional>
      </dependency>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-test</artifactId>
         <scope>test</scope>
      </dependency>
   </dependencies>
   <build>
      <plugins>
         <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
               <excludes>
                  <exclude>
                     <groupId>org.projectlombok</groupId>
                     <artifactId>lombok</artifactId>
                  </exclude>
               </excludes>
            </configuration>
         </plugin>
      </plugins>
   </build>
   <profiles>
      <profile>
         <id>lambda</id>
         <activation>
            <activeByDefault>true</activeByDefault>
         </activation>
         <dependencies>
            <dependency>
               <groupId>org.springframework.boot</groupId>
               <artifactId>spring-boot-starter-web</artifactId>
               <exclusions>
                  <exclusion>
                     <groupId>org.springframework.boot</groupId>
                     <artifactId>spring-boot-starter-tomcat</artifactId>
                  </exclusion>
               </exclusions>
            </dependency>
            <dependency>
               <groupId>com.amazonaws.serverless</groupId>
               <artifactId>aws-serverless-java-container-springboot3</artifactId>
               <version>2.0.0</version>
            </dependency>
         </dependencies>
         <build>
            <plugins>
               <plugin>
                  <groupId>org.apache.maven.plugins</groupId>
                  <artifactId>maven-shade-plugin</artifactId>
                  <version>3.5.1</version>
                  <configuration>
                     <createDependencyReducedPom>false</createDependencyReducedPom>
                  </configuration>
                  <executions>
                     <execution>
                        <phase>package</phase>
                        <goals>
                           <goal>shade</goal>
                        </goals>
                        <configuration>
                           <artifactSet>
                              <excludes>
                                 <exclude>org.apache.tomcat.embed:*</exclude>
                              </excludes>
                           </artifactSet>
                        </configuration>
                     </execution>
                  </executions>
               </plugin>
            </plugins>
         </build>
      </profile>
   </profiles>
</project>

Also, my serverless.yml:

service: espaidoc

provider:
  name: aws
  runtime: java17
  stage: dev
  region: us-east-1
  versionFunctions: false

package:
  artifact: ./target/frontoffice-0.0.1-SNAPSHOT.jar

plugins:
  - serverless-localstack

custom:
  localstack:
    stages:
      - dev
    host: localstack.localhost
    edgePort: 8000
    endpointFile: .localstack/endpoints.json

functions:
  api:
    handler: com.amazonaws.serverless.proxy.spring.SpringBootLambdaContainerHandler::handleRequest
    environment:
      MAIN_CLASS: FluxApplication
    events:
      - http:
          method: POST
          path: /documents

Any ideas?

@deki
Copy link
Collaborator

deki commented Feb 22, 2024

Hi,
take a look at https://aws.amazon.com/blogs/compute/re-platforming-java-applications-using-the-updated-aws-serverless-java-container/.

You can configure and use the SpringDelegatingLambdaContainerHandler implementation or implement your own handler Java class that delegates to AWS Serverless Java Container.

In your case the easiest fix is replacing
handler: com.amazonaws.serverless.proxy.spring.SpringBootLambdaContainerHandler::handleRequest
with
handler: com.amazonaws.serverless.proxy.spring.SpringDelegatingLambdaContainerHandler
in your serverless.yml.

@deki deki added the question label Feb 22, 2024
@jeusdi
Copy link
Author

jeusdi commented Feb 22, 2024

I think I'm almost there.

I'm getting this message now:

2024-02-22T14:41:01.451 WARN --- [ asgi_gw_0] l.s.apigateway.integration : Lambda output should follow the next JSON format: { "isBase64Encoded": true|false, "statusCode": httpStatusCode, "headers": { "headerName": "headerValue", ... },"body": "..."}
Lambda output: {'errorMessage': 'Could not find class [FluxApplication]', 'errorType': 'java.lang.IllegalArgumentException'}

I've took a look on uploaded jar:

$ jar tf target/frontoffice-0.0.1-SNAPSHOT.jar | grep FluxApplication
me/jeusdi/slab/localstack/flux/presentation/frontoffice/FluxApplication.class

As you can see, FluxApplication in on jar file.

FluxApplication class is:

package me.jeusdi.slab.localstack.flux.presentation.frontoffice;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.FilterType;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;

import me.jeusdi.slab.localstack.flux.application.document.pull.PullDocumentInputPort;
import me.jeusdi.slab.localstack.flux.application.document.push.PushDocumentInputPort;
import me.jeusdi.slab.localstack.flux.application.document.push.PushDocumentPersistenceGatewayOutputPort;
import me.jeusdi.slab.localstack.flux.application.document.pushed.PushedDocumentPersistenceGatewayOutputPort;
import me.jeusdi.slab.localstack.flux.domain.model.document.PullDocumentService;
import me.jeusdi.slab.localstack.flux.domain.model.document.PushDocumentService;
import me.jeusdi.slab.localstack.flux.domain.model.document.ResourceProvider;
import me.jeusdi.slab.localstack.flux.infrastructure.repository.ResourceMongoRespository;

@SpringBootApplication
@ComponentScan
@ComponentScan(basePackages = "me.jeusdi.slab.localstack.flux.domain.model.document", includeFilters = {
		@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = PullDocumentService.class),
		@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = PushDocumentService.class),
})
@ComponentScan(basePackages = "me.jeusdi.slab.localstack.flux.application", includeFilters = {
		@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = PushDocumentInputPort.class),
		@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = PullDocumentInputPort.class)
})
@ComponentScan(basePackages = "me.jeusdi.slab.localstack.flux.infrastructure", includeFilters = {
		@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = ResourceProvider.class),
		@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = PushDocumentPersistenceGatewayOutputPort.class),
		@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = PushedDocumentPersistenceGatewayOutputPort.class),
		@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = ResourceMongoRespository.class)
})
@EnableMongoRepositories(basePackages = "me.jeusdi.slab.localstack.flux.infrastructure")
public class FluxApplication {

	public static void main(String[] args) {
		SpringApplication.run(FluxApplication.class, args);
	}

}

In order to set with "main" to pick up for DelegateContainer, I've set MAIN_CLASS environment variable to "FluxApplication" into serverless.yml:

service: espaidoc

provider:
  name: aws
  runtime: java17
  stage: dev
  region: us-east-1
  versionFunctions: false

package:
  artifact: ./target/frontoffice-0.0.1-SNAPSHOT.jar

plugins:
  - serverless-localstack

custom:
  localstack:
    stages:
      - dev
    host: localstack.localhost
    edgePort: 8000
    endpointFile: .localstack/endpoints.json

functions:
  api:
    handler: com.amazonaws.serverless.proxy.spring.SpringDelegatingLambdaContainerHandler
    environment:
      MAIN_CLASS: FluxApplication
    events:
      - http:
          method: POST
          path: /documents

Any ideas?

@deki
Copy link
Collaborator

deki commented Feb 22, 2024

Yeah it has to be a fully qualified class name including the package. So in your case:
MAIN_CLASS: me.jeusdi.slab.localstack.flux.presentation.frontoffice.FluxApplication

@jeusdi
Copy link
Author

jeusdi commented Feb 22, 2024

Thanks @deki . I was solved it using fully qualified class name.

Another issue here:

I'm getting:

2024-02-22T15:09:13.612 WARN --- [ asgi_gw_3] l.s.apigateway.integration : Lambda output should follow the next JSON format: { "isBase64Encoded": true|false, "statusCode": httpStatusCode, "headers": { "headerName": "headerValue", ... },"body": "..."}
Lambda output: {'errorMessage': 'java.lang.NullPointerException: Cannot invoke "org.springframework.web.servlet.DispatcherServlet.getServletContext()" because "servlet" is null', 'errorType': 'java.lang.IllegalStateException', 'stackTrace': ['com.amazonaws.serverless.proxy.spring.AwsSpringHttpProcessingUtils.processRequest(AwsSpringHttpProcessingUtils.java:61)', 'com.amazonaws.serverless.proxy.spring.SpringDelegatingLambdaContainerHandler.handleRequest(SpringDelegatingLambdaContainerHandler.java:64)'], 'cause': {'errorMessage': 'Cannot invoke "org.springframework.web.servlet.DispatcherServlet.getServletContext()" because "servlet" is null', 'errorType': 'java.lang.NullPointerException', 'stackTrace': ['org.springframework.cloud.function.serverless.web.ServerlessMVC$ProxyFilterChain.(ServerlessMVC.java:224)', 'org.springframework.cloud.function.serverless.web.ServerlessMVC.service(ServerlessMVC.java:167)', 'org.springframework.cloud.function.serverless.web.ServerlessMVC.service(ServerlessMVC.java:163)', 'com.amazonaws.serverless.proxy.spring.AwsSpringHttpProcessingUtils.processRequest(AwsSpringHttpProcessingUtils.java:51)', 'com.amazonaws.serverless.proxy.spring.SpringDelegatingLambdaContainerHandler.handleRequest(SpringDelegatingLambdaContainerHandler.java:64)']}}

Any suggestion here?

EDIT

I've also tested trying to invoke my function using serverless framework getting the same but more detailed logs. Here the output:

$ sls invoke local --function "api"
(node:10982) NOTE: We are formalizing our plans to enter AWS SDK for JavaScript (v2) into maintenance mode in
2023.

Please migrate your code to use AWS SDK for JavaScript (v3).
For more information, check the migration guide at https://a.co/7PzMCcy
(Use `sls --trace-warnings ...` to show where the warning was created)
Using serverless-localstack
serverless-localstack: Reconfigured endpoints
Warning: In order to get human-readable output, please implement "toString()" method of your "ApiGatewayRespon
se" object.
Standard Commons Logging discovery in action with spring-jcl: please remove commons-logging.jar from classpath
 in order to avoid potential conflicts

19:36:43.582 [main] INFO org.springframework.cloud.function.serverless.web.FunctionClassUtils -- Main class: c
lass me.jeusdi.slab.localstack.flux.presentation.frontoffice.FluxApplication

19:36:43.641 [Thread-0] INFO org.springframework.cloud.function.serverless.web.ServerlessMVC -- Starting application with the following configuration classes:

19:36:43.644 [Thread-0] INFO org.springframework.cloud.function.serverless.web.ServerlessMVC -- FluxApplication


  .   ____          _            __ _ _

 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/

 :: Spring Boot ::                (v3.2.2)



2024-02-22T19:36:45.258+01:00  INFO 11078 --- [       Thread-0] o.s.boot.SpringApplication               : Starting application using Java 21.0.1 with PID 11078 (started by jcabre in /home/jcabre/projects/gene/cultura/espa

2024-02-22T19:36:45.261+01:00  INFO 11078 --- [       Thread-0] o.s.boot.SpringApplication               : No active profile set, falling back to 1 default profile: "default"

2024-02-22T19:36:45.740+01:00 DEBUG 11078 --- [       Thread-0] o.s.c.a.ClassPathBeanDefinitionScanner   : Identified candidate component class: URL [jar:file:/home/jcabre/projects/gene/cultura/espaidoc/workarea/repositori

2024-02-22T19:36:45.805+01:00 DEBUG 11078 --- [       Thread-0] o.s.c.a.ClassPathBeanDefinitionScanner   : Identified candidate component class: URL [jar:file:/home/jcabre/projects/gene/cultura/espaidoc/workarea/repositori

2024-02-22T19:36:45.819+01:00 DEBUG 11078 --- [       Thread-0] o.s.c.a.ClassPathBeanDefinitionScanner   : Identified candidate component class: URL [jar:file:/home/jcabre/projects/gene/cultura/espaidoc/workarea/repositori

2024-02-22T19:36:45.846+01:00 DEBUG 11078 --- [       Thread-0] o.s.c.a.ClassPathBeanDefinitionScanner   : Identified candidate component class: URL [jar:file:/home/jcabre/projects/gene/cultura/espaidoc/workarea/repositori

2024-02-22T19:36:45.847+01:00 DEBUG 11078 --- [       Thread-0] o.s.c.a.ClassPathBeanDefinitionScanner   : Ignored because not a concrete top-level class: URL [jar:file:/home/jcabre/projects/gene/cultura/espaidoc/workarea/
2024-02-22T19:36:45.848+01:00 DEBUG 11078 --- [       Thread-0] o.s.c.a.ClassPathBeanDefinitionScanner   : Identified candidate component class: URL [jar:file:/home/jcabre/projects/gene/cultura/espaidoc/workarea/repositori
2024-02-22T19:36:45.848+01:00 DEBUG 11078 --- [       Thread-0] o.s.c.a.ClassPathBeanDefinitionScanner   : Ignored because not a concrete top-level class: URL [jar:file:/home/jcabre/projects/gene/cultura/espaidoc/workarea/

2024-02-22T19:36:45.895+01:00 DEBUG 11078 --- [       Thread-0] o.s.c.a.ClassPathBeanDefinitionScanner   : Ignored because not a concrete top-level class: URL [jar:file:/home/jcabre/projects/gene/cultura/espaidoc/workarea/

2024-02-22T19:36:45.900+01:00 DEBUG 11078 --- [       Thread-0] o.s.c.a.ClassPathBeanDefinitionScanner   : Identified candidate component class: URL [jar:file:/home/jcabre/projects/gene/cultura/espaidoc/workarea/repositori

2024-02-22T19:36:45.907+01:00 DEBUG 11078 --- [       Thread-0] o.s.c.a.ClassPathBeanDefinitionScanner   : Identified candidate component class: URL [jar:file:/home/jcabre/projects/gene/cultura/espaidoc/workarea/repositori

2024-02-22T19:36:47.289+01:00  INFO 11078 --- [       Thread-0] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data MongoDB repositories in DEFAULT mode.

2024-02-22T19:36:47.472+01:00  INFO 11078 --- [       Thread-0] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 170 ms. Found 1 MongoDB repository interface.

2024-02-22T19:36:48.888+01:00  WARN 11078 --- [       Thread-0] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.Appli

2024-02-22T19:36:48.975+01:00 ERROR 11078 --- [       Thread-0] o.s.b.d.LoggingFailureAnalysisReporter   :

***************************
APPLICATION FAILED TO START
***************************

Description:

Web application could not be started as there was no org.springframework.boot.web.servlet.server.ServletWebServerFactory bean defined in the context.

Action:

Check your application's dependencies for a supported servlet web server.
Check the configured web application type.


2024-02-22T19:36:48.979+01:00  INFO 11078 --- [       Thread-0] o.s.c.f.serverless.web.ServerlessMVC     : Application is started successfully.

Exception in thread "Thread-0" java.lang.IllegalStateException: org.springframework.context.ApplicationContextException: Unable to start web server
        at org.springframework.cloud.function.serverless.web.ServerlessMVC.lambda$initializeContextAsync$1(ServerlessMVC.java:116)
        at java.base/java.lang.Thread.run(Thread.java:1583)
Caused by: org.springframework.context.ApplicationContextException: Unable to start web server
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:165)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:618)
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146)

        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754)

        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:334)

        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1354)
        at org.springframework.cloud.function.serverless.web.ServerlessMVC.initContext(ServerlessMVC.java:126)
        at org.springframework.cloud.function.serverless.web.ServerlessMVC.lambda$initializeContextAsync$1(ServerlessMVC.java:113)
        ... 1 more
Caused by: org.springframework.boot.web.context.MissingWebServerFactoryBeanException: No qualifying bean of type 'org.springframework.boot.web.servlet.server.ServletWebServerFactory' available: Unable to start AnnotationCo
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.getWebServerFactory(ServletWebServerApplicationContext.java:216)
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:186)
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:162)
        ... 9 more

java.lang.NullPointerException: Cannot invoke "org.springframework.web.servlet.DispatcherServlet.getServletContext()" because "servlet" is null
        at org.springframework.cloud.function.serverless.web.ServerlessMVC$ProxyFilterChain.<init>(ServerlessMVC.java:224)
        at org.springframework.cloud.function.serverless.web.ServerlessMVC.service(ServerlessMVC.java:167)
        at org.springframework.cloud.function.serverless.web.ServerlessMVC.service(ServerlessMVC.java:163)
        at com.amazonaws.serverless.proxy.spring.AwsSpringHttpProcessingUtils.processRequest(AwsSpringHttpProcessingUtils.java:51)
        at com.amazonaws.serverless.proxy.spring.SpringDelegatingLambdaContainerHandler.handleRequest(SpringDelegatingLambdaContainerHandler.java:64)
        at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
        at java.base/java.lang.reflect.Method.invoke(Method.java:580)
        at com.serverless.InvokeBridge.invoke(InvokeBridge.java:86)
        at com.serverless.InvokeBridge.<init>(InvokeBridge.java:38)
        at com.serverless.InvokeBridge.main(InvokeBridge.java:137)

java.lang.reflect.InvocationTargetException
        at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:118)
        at java.base/java.lang.reflect.Method.invoke(Method.java:580)
        at com.serverless.InvokeBridge.invoke(InvokeBridge.java:86)
        at com.serverless.InvokeBridge.<init>(InvokeBridge.java:38)
        at com.serverless.InvokeBridge.main(InvokeBridge.java:137)
Caused by: java.lang.IllegalStateException: java.lang.NullPointerException: Cannot invoke "org.springframework.web.servlet.DispatcherServlet.getServletContext()" because "servlet" is null
        at com.amazonaws.serverless.proxy.spring.AwsSpringHttpProcessingUtils.processRequest(AwsSpringHttpProcessingUtils.java:61)
        at com.amazonaws.serverless.proxy.spring.SpringDelegatingLambdaContainerHandler.handleRequest(SpringDelegatingLambdaContainerHandler.java:64)
        at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
        ... 4 more
Caused by: java.lang.NullPointerException: Cannot invoke "org.springframework.web.servlet.DispatcherServlet.getServletContext()" because "servlet" is null
        at org.springframework.cloud.function.serverless.web.ServerlessMVC$ProxyFilterChain.<init>(ServerlessMVC.java:224)
        at org.springframework.cloud.function.serverless.web.ServerlessMVC.service(ServerlessMVC.java:167)

        at org.springframework.cloud.function.serverless.web.ServerlessMVC.service(ServerlessMVC.java:163)
        at com.amazonaws.serverless.proxy.spring.AwsSpringHttpProcessingUtils.processRequest(AwsSpringHttpProcessingUtils.java:51)
        ... 6 more

@deki
Copy link
Collaborator

deki commented Feb 22, 2024

@olegz can you look into this one?

@fabiencoppens
Copy link

I'm running into the exact same problem that @jeusdi is running into, i.e. Caused by: java.lang.NullPointerException: Cannot invoke "org.springframework.web.servlet.DispatcherServlet.getServletContext()" because "servlet" is null
I've tried both versions 2.0.0 and 2.0.1 of aws-serverless-java-container-springboot3, and get that same error stack.
Any updates please?

@deki
Copy link
Collaborator

deki commented Apr 12, 2024

see also #819 it seems to be webflux related. we'll take a look...

@olegz
Copy link
Collaborator

olegz commented Apr 15, 2024

I have not tested it with webflux, so at this point it is safe to say it is not supported. Not saying it can not be supported, but DispatcherServlet model is not really for webflux

@olegz
Copy link
Collaborator

olegz commented Apr 15, 2024

Also, based on your stack trace it appears you can't start the application at all. That is strange since it appears spring-cloud-function-serverless-web auto-configuration is not picked up as if it is not on the classpath. Can you please re-post the POM that you currently have? Better of provide a sample app that reproduces the issue

@fabiencoppens
Copy link

@olegz @deki I actually created a separate ticket last week for my issue, and it has my full stack trace: #828
We have webflux in our dependencies, but we don't really leverage it, as all our APIs are traditional blocking I/O. I'll try to exclude webflux and see if that fixes the issue.
Is there also a workaround if we wanted to keep webflux?

@olegz
Copy link
Collaborator

olegz commented Apr 24, 2024

@fabiencoppens I was on PTO and getting back to it now. Give me few days and I'll see what is going on

@olegz
Copy link
Collaborator

olegz commented Apr 24, 2024

@fabiencoppens @deki I just used your POM from the above comments and everything works as expected, so what am I missing?
FWIW, here is my template.yaml

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Example Pet Store API written with spring-cloud-function web-proxy support

Globals:
  Api:
    # API Gateway regional endpoints
    EndpointConfiguration: REGIONAL

Resources:
  PetStoreMVC:
    Type: AWS::Serverless::Function
    Properties:
#      AutoPublishAlias: bcn
      FunctionName: pet-store-boot-3
      Handler: com.amazonaws.serverless.proxy.spring.SpringDelegatingLambdaContainerHandler::handleRequest
      Runtime: java17
      SnapStart:
        ApplyOn: PublishedVersions
      CodeUri: .
      MemorySize: 1024
      Policies: AWSLambdaBasicExecutionRole
      Timeout: 30
      Environment:
        Variables:
          MAIN_CLASS: io.spring.sample.springboot3.Application
      Events:
        HttpApiEvent:
          Type: HttpApi
          Properties:
            TimeoutInMillis: 20000
            PayloadFormatVersion: '1.0'

Outputs:
  PetStoreMVCApi:
    Description: URL for application
    Value: !Sub 'https://${ServerlessHttpApi}.execute-api.${AWS::Region}.amazonaws.com/pets'
    Export:
      Name: PetStoreMVCApi

And here is the full POM.xml which is pretty much a copy of what you have up above in the comments. In fact I am not seeing eny webflux there, so it puzzles me even more when you say you are using it

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>io.spring.sample</groupId>
    <artifactId>mvc-aws</artifactId>
    <version>2.0-SNAPSHOT</version>
    <name>Spring Boot example for the aws-serverless-java-container library</name>
    <description>Simple pet store written with the Spring framework and Spring Boot</description>
    <url>https://aws.amazon.com/lambda/</url>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.2</version>
    </parent>

    <licenses>
        <license>
            <name>The Apache Software License, Version 2.0</name>
            <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
            <distribution>repo</distribution>
        </license>
    </licenses>

    <properties>
      <java.version>17</java.version>
      <spring-boot-dependencies.version>3.2.2</spring-boot-dependencies.version>
      <spring-cloud-aws.version>3.1.0</spring-cloud-aws.version>
   </properties>
   <dependencyManagement>
      <dependencies>
         <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>${spring-boot-dependencies.version}</version>
            <type>pom</type>
            <scope>import</scope>
         </dependency>
         <dependency>
            <groupId>io.awspring.cloud</groupId>
            <artifactId>spring-cloud-aws-dependencies</artifactId>
            <version>${spring-cloud-aws.version}</version>
            <type>pom</type>
            <scope>import</scope>
         </dependency>
      </dependencies>
   </dependencyManagement>
   <dependencies>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-web</artifactId>
      </dependency>
      <dependency>
         <groupId>io.awspring.cloud</groupId>
         <artifactId>spring-cloud-aws-starter-s3</artifactId>
      </dependency>
      <dependency>
         <groupId>io.awspring.cloud</groupId>
         <artifactId>spring-cloud-aws-starter-sqs</artifactId>
      </dependency>
      <dependency>
         <groupId>org.projectlombok</groupId>
         <artifactId>lombok</artifactId>
         <optional>true</optional>
      </dependency>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-test</artifactId>
         <scope>test</scope>
      </dependency>
   </dependencies>
   <build>
      <plugins>
         <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
               <excludes>
                  <exclude>
                     <groupId>org.projectlombok</groupId>
                     <artifactId>lombok</artifactId>
                  </exclude>
               </excludes>
            </configuration>
         </plugin>
      </plugins>
   </build>
   <profiles>
      <profile>
         <id>lambda</id>
         <activation>
            <activeByDefault>true</activeByDefault>
         </activation>
         <dependencies>
            <dependency>
               <groupId>org.springframework.boot</groupId>
               <artifactId>spring-boot-starter-web</artifactId>
               <exclusions>
                  <exclusion>
                     <groupId>org.springframework.boot</groupId>
                     <artifactId>spring-boot-starter-tomcat</artifactId>
                  </exclusion>
               </exclusions>
            </dependency>
            <dependency>
               <groupId>com.amazonaws.serverless</groupId>
               <artifactId>aws-serverless-java-container-springboot3</artifactId>
               <version>2.0.0</version>
            </dependency>
         </dependencies>
         <build>
            <plugins>
               <plugin>
                  <groupId>org.apache.maven.plugins</groupId>
                  <artifactId>maven-shade-plugin</artifactId>
                  <version>3.5.1</version>
                  <configuration>
                     <createDependencyReducedPom>false</createDependencyReducedPom>
                  </configuration>
                  <executions>
                     <execution>
                        <phase>package</phase>
                        <goals>
                           <goal>shade</goal>
                        </goals>
                        <configuration>
                           <artifactSet>
                              <excludes>
                                 <exclude>org.apache.tomcat.embed:*</exclude>
                              </excludes>
                           </artifactSet>
                        </configuration>
                     </execution>
                  </executions>
               </plugin>
            </plugins>
         </build>
      </profile>
   </profiles>
</project>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants