aws/serverless-java-container

ServletContext: Servlet.getServletConfig() is null

eddpascoal opened this issue · 1 comments

Serverless Java Container version: 2.0.0

Implementations: Spring Boot 3

Framework version: SpringBoot3.0.6

Frontend service: API GATEWAY using SpringBootLambdaContainerHandler

Deployment method: eg Cloudformation (using CDK)

Scenario

I want to retrieve header information from API Gateway (authorizer) to my Springboot application.

Expected behavior

I would expect that I would be able to fetch some information (e.g. CognitoIdentity) by adding a filter on startup of the SpringBootLambdaContainerHandler would work

Actual behavior

Error is raised as java.lang.NullPointerException: Cannot invoke "jakarta.servlet.ServletConfig.getServletName()" because the return value of "jakarta.servlet.Servlet.getServletConfig()" is null

Steps to reproduce

I'm following the example of Pet Store from serverless/sample/springboot3
running from a local lambda.

FROM gradle:7-jdk17-alpine AS build
COPY --chown=gradle:gradle . /home/gradle/src
WORKDIR /home/gradle/src
RUN gradle build -x test --no-daemon 

FROM openjdk:17-jdk-alpine as local
EXPOSE 8080
RUN mkdir /app
WORKDIR /app
COPY . /app
COPY --from=build  /home/gradle/src/build/libs/*.jar /app/myapp.jar
CMD ["java", "-jar","/app/myapp.jar"]

FROM public.ecr.aws/lambda/java:21 AS lambda

# Copy function code and runtime dependencies from Gradle layout
COPY --from=build  /home/gradle/src/build/classes/kotlin/main ${LAMBDA_TASK_ROOT}
COPY --from=build  /home/gradle/src/build/dependency/* ${LAMBDA_TASK_ROOT}/lib/
COPY --from=build  /home/gradle/src/build/resources/main/* ${LAMBDA_TASK_ROOT}

CMD [ "StreamLambdaHandler::handleRequest"]
class StreamLambdaHandler : RequestStreamHandler {
    init {
        // we enable the timer for debugging. This SHOULD NOT be enabled in production.
        Timer.enable()
    }

    @Throws(IOException::class)
    override fun handleRequest(inputStream: InputStream, outputStream: OutputStream, context: Context) {
        handler!!.proxyStream(inputStream, outputStream, context)
    }

    companion object {
        private var handler: SpringBootLambdaContainerHandler<AwsProxyRequest, AwsProxyResponse>? = null

        init {
            try {
                handler = SpringBootLambdaContainerHandler.getAwsProxyHandler(ApiApplication::class.java)

                // we use the onStartup method of the handler to register our custom filter
                (handler as SpringBootLambdaContainerHandler<AwsProxyRequest, AwsProxyResponse>?)?.onStartup { servletContext: ServletContext ->

                    val registration = servletContext.addFilter(
                        "CognitoIdentityFilter",
                        CognitoIdentityFilter::class.java
                    )
                    registration.addMappingForUrlPatterns(
                        EnumSet.of(DispatcherType.REQUEST),
                        true,
                        "/*"
                    )
                }
            } catch (e: ContainerInitializationException) {
                // if we fail here. We re-throw the exception to force another cold start
                e.printStackTrace()
                throw RuntimeException("Could not initialize Spring Boot application", e)
            }
        }
    }
}

Full log output

Docker container log:running from a local lambda

2024-04-08 08:12:55 2024-04-07T20:12:55.203Z  INFO 14 --- [           main] c.a.s.l.runtime.api.client.AWSLambda     : Started AWSLambda in 7.385 seconds (process running for 8.958)
2024-04-08 08:12:55 07 Apr 2024 20:12:55,460 [INFO] (rapid) INIT RTDONE(status: success)
2024-04-08 08:12:55 07 Apr 2024 20:12:55,460 [INFO] (rapid) INIT REPORT(durationMs: 9221.763000)
2024-04-08 08:12:55 07 Apr 2024 20:12:55,460 [INFO] (rapid) INVOKE START(requestId: 2c3a71d5-abbb-4482-8987-b45013a830e6)
2024-04-08 08:12:55 2024-04-07T20:12:55.488Z ERROR 14 --- [           main] c.a.s.p.internal.LambdaContainerHandler  : Error while handling request
2024-04-08 08:12:55 
2024-04-08 08:12:55 java.lang.NullPointerException: Cannot invoke "jakarta.servlet.ServletConfig.getServletName()" because the return value of "jakarta.servlet.Servlet.getServletConfig()" is null
2024-04-08 08:12:55     at com.amazonaws.serverless.proxy.internal.servlet.FilterChainManager.putFilterChainCache(FilterChainManager.java:188) ~[aws-serverless-java-container-core-2.0.0.jar:na]
2024-04-08 08:12:55     at com.amazonaws.serverless.proxy.internal.servlet.FilterChainManager.getFilterChain(FilterChainManager.java:135) ~[aws-serverless-java-container-core-2.0.0.jar:na]
2024-04-08 08:12:55     at com.amazonaws.serverless.proxy.internal.servlet.AwsLambdaServletContainerHandler.getFilterChain(AwsLambdaServletContainerHandler.java:132) ~[aws-serverless-java-container-core-2.0.0.jar:na]
2024-04-08 08:12:55     at com.amazonaws.serverless.proxy.internal.servlet.AwsLambdaServletContainerHandler.doFilter(AwsLambdaServletContainerHandler.java:153) ~[aws-serverless-java-container-core-2.0.0.jar:na]
2024-04-08 08:12:55     at com.amazonaws.serverless.proxy.spring.SpringBootLambdaContainerHandler.handleRequest(SpringBootLambdaContainerHandler.java:183) ~[aws-serverless-java-container-springboot3-2.0.0.jar:na]
2024-04-08 08:12:55     at com.amazonaws.serverless.proxy.spring.SpringBootLambdaContainerHandler.handleRequest(SpringBootLambdaContainerHandler.java:56) ~[aws-serverless-java-container-springboot3-2.0.0.jar:na]
2024-04-08 08:12:55     at com.amazonaws.serverless.proxy.internal.LambdaContainerHandler.proxy(LambdaContainerHandler.java:215) ~[aws-serverless-java-container-core-2.0.0.jar:na]
2024-04-08 08:12:55     at com.amazonaws.serverless.proxy.internal.LambdaContainerHandler.proxyStream(LambdaContainerHandler.java:258) ~[aws-serverless-java-container-core-2.0.0.jar:na]
2024-04-08 08:12:55     at StreamLambdaHandler.handleRequest(StreamLambdaHandler.kt:27) ~[task/:na]
2024-04-08 08:12:55     at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(Unknown Source) ~[na:na]
2024-04-08 08:12:55     at java.base/java.lang.reflect.Method.invoke(Unknown Source) ~[na:na]
2024-04-08 08:12:55     at com.amazonaws.services.lambda.runtime.api.client.EventHandlerLoader$StreamMethodRequestHandler.handleRequest(EventHandlerLoader.java:378) ~[aws-lambda-java-runtime-interface-client-2.4.1-linux-x86_64.jar:2.4.1]
2024-04-08 08:12:55     at com.amazonaws.services.lambda.runtime.api.client.EventHandlerLoader$2.call(EventHandlerLoader.java:905) ~[aws-lambda-java-runtime-interface-client-2.4.1-linux-x86_64.jar:2.4.1]
2024-04-08 08:12:55     at com.amazonaws.services.lambda.runtime.api.client.AWSLambda.startRuntime(AWSLambda.java:245) ~[aws-lambda-java-runtime-interface-client-2.4.1-linux-x86_64.jar:2.4.1]
2024-04-08 08:12:55     at com.amazonaws.services.lambda.runtime.api.client.AWSLambda.startRuntime(AWSLambda.java:197) ~[aws-lambda-java-runtime-interface-client-2.4.1-linux-x86_64.jar:2.4.1]
2024-04-08 08:12:55     at com.amazonaws.services.lambda.runtime.api.client.AWSLambda.main(AWSLambda.java:187) ~[aws-lambda-java-runtime-interface-client-2.4.1-linux-x86_64.jar:2.4.1]
2024-04-08 08:12:55 
2024-04-08 08:12:55 2024-04-07T20:12:55.494Z ERROR 14 --- [           main] c.a.s.proxy.AwsProxyExceptionHandler     : Called exception handler for:
2024-04-08 08:12:55 
2024-04-08 08:12:55 java.lang.NullPointerException: Cannot invoke "jakarta.servlet.ServletConfig.getServletName()" because the return value of "jakarta.servlet.Servlet.getServletConfig()" is null
2024-04-08 08:12:55     at com.amazonaws.serverless.proxy.internal.servlet.FilterChainManager.putFilterChainCache(FilterChainManager.java:188) ~[aws-serverless-java-container-core-2.0.0.jar:na]
2024-04-08 08:12:55     at com.amazonaws.serverless.proxy.internal.servlet.FilterChainManager.getFilterChain(FilterChainManager.java:135) ~[aws-serverless-java-container-core-2.0.0.jar:na]
2024-04-08 08:12:55     at com.amazonaws.serverless.proxy.internal.servlet.AwsLambdaServletContainerHandler.getFilterChain(AwsLambdaServletContainerHandler.java:132) ~[aws-serverless-java-container-core-2.0.0.jar:na]
2024-04-08 08:12:55     at com.amazonaws.serverless.proxy.internal.servlet.AwsLambdaServletContainerHandler.doFilter(AwsLambdaServletContainerHandler.java:153) ~[aws-serverless-java-container-core-2.0.0.jar:na]
2024-04-08 08:12:55     at com.amazonaws.serverless.proxy.spring.SpringBootLambdaContainerHandler.handleRequest(SpringBootLambdaContainerHandler.java:183) ~[aws-serverless-java-container-springboot3-2.0.0.jar:na]
2024-04-08 08:12:55     at com.amazonaws.serverless.proxy.spring.SpringBootLambdaContainerHandler.handleRequest(SpringBootLambdaContainerHandler.java:56) ~[aws-serverless-java-container-springboot3-2.0.0.jar:na]
2024-04-08 08:12:55     at com.amazonaws.serverless.proxy.internal.LambdaContainerHandler.proxy(LambdaContainerHandler.java:215) ~[aws-serverless-java-container-core-2.0.0.jar:na]
2024-04-08 08:12:55     at com.amazonaws.serverless.proxy.internal.LambdaContainerHandler.proxyStream(LambdaContainerHandler.java:258) ~[aws-serverless-java-container-core-2.0.0.jar:na]
2024-04-08 08:12:55     at StreamLambdaHandler.handleRequest(StreamLambdaHandler.kt:27) ~[task/:na]
2024-04-08 08:12:55     at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(Unknown Source) ~[na:na]
2024-04-08 08:12:55     at java.base/java.lang.reflect.Method.invoke(Unknown Source) ~[na:na]
2024-04-08 08:12:55     at com.amazonaws.services.lambda.runtime.api.client.EventHandlerLoader$StreamMethodRequestHandler.handleRequest(EventHandlerLoader.java:378) ~[aws-lambda-java-runtime-interface-client-2.4.1-linux-x86_64.jar:2.4.1]
2024-04-08 08:12:55     at com.amazonaws.services.lambda.runtime.api.client.EventHandlerLoader$2.call(EventHandlerLoader.java:905) ~[aws-lambda-java-runtime-interface-client-2.4.1-linux-x86_64.jar:2.4.1]
2024-04-08 08:12:55     at com.amazonaws.services.lambda.runtime.api.client.AWSLambda.startRuntime(AWSLambda.java:245) ~[aws-lambda-java-runtime-interface-client-2.4.1-linux-x86_64.jar:2.4.1]
2024-04-08 08:12:55     at com.amazonaws.services.lambda.runtime.api.client.AWSLambda.startRuntime(AWSLambda.java:197) ~[aws-lambda-java-runtime-interface-client-2.4.1-linux-x86_64.jar:2.4.1]
2024-04-08 08:12:55     at com.amazonaws.services.lambda.runtime.api.client.AWSLambda.main(AWSLambda.java:187) ~[aws-lambda-java-runtime-interface-client-2.4.1-linux-x86_64.jar:2.4.1]
2024-04-08 08:12:55 
2024-04-08 08:12:55 java.lang.NullPointerException: Cannot invoke "jakarta.servlet.ServletConfig.getServletName()" because the return value of "jakarta.servlet.Servlet.getServletConfig()" is null
2024-04-08 08:12:55     at com.amazonaws.serverless.proxy.internal.servlet.FilterChainManager.putFilterChainCache(FilterChainManager.java:188)
2024-04-08 08:12:55     at com.amazonaws.serverless.proxy.internal.servlet.FilterChainManager.getFilterChain(FilterChainManager.java:135)
2024-04-08 08:12:55     at com.amazonaws.serverless.proxy.internal.servlet.AwsLambdaServletContainerHandler.getFilterChain(AwsLambdaServletContainerHandler.java:132)
2024-04-08 08:12:55     at com.amazonaws.serverless.proxy.internal.servlet.AwsLambdaServletContainerHandler.doFilter(AwsLambdaServletContainerHandler.java:153)
2024-04-08 08:12:55     at com.amazonaws.serverless.proxy.spring.SpringBootLambdaContainerHandler.handleRequest(SpringBootLambdaContainerHandler.java:183)
2024-04-08 08:12:55     at com.amazonaws.serverless.proxy.spring.SpringBootLambdaContainerHandler.handleRequest(SpringBootLambdaContainerHandler.java:56)
2024-04-08 08:12:55     at com.amazonaws.serverless.proxy.internal.LambdaContainerHandler.proxy(LambdaContainerHandler.java:215)
2024-04-08 08:12:55     at com.amazonaws.serverless.proxy.internal.LambdaContainerHandler.proxyStream(LambdaContainerHandler.java:258)
2024-04-08 08:12:55     at StreamLambdaHandler.handleRequest(StreamLambdaHandler.kt:27)
2024-04-08 08:12:55     at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(Unknown Source)
2024-04-08 08:12:55     at java.base/java.lang.reflect.Method.invoke(Unknown Source)
2024-04-08 08:12:55     at com.amazonaws.services.lambda.runtime.api.client.EventHandlerLoader$StreamMethodRequestHandler.handleRequest(EventHandlerLoader.java:378)
2024-04-08 08:12:55     at com.amazonaws.services.lambda.runtime.api.client.EventHandlerLoader$2.call(EventHandlerLoader.java:905)
2024-04-08 08:12:55     at com.amazonaws.services.lambda.runtime.api.client.AWSLambda.startRuntime(AWSLambda.java:245)
2024-04-08 08:12:55     at com.amazonaws.services.lambda.runtime.api.client.AWSLambda.startRuntime(AWSLambda.java:197)
2024-04-08 08:12:55     at com.amazonaws.services.lambda.runtime.api.client.AWSLambda.main(AWSLambda.java:187)
2024-04-08 08:12:55 END RequestId: 2c3a71d5-abbb-4482-8987-b45013a830e6
2024-04-08 08:12:55 REPORT RequestId: 2c3a71d5-abbb-4482-8987-b45013a830e6      Init Duration: 0.04 ms  Duration: 9284.76 ms    Billed Duration: 9285 ms        Memory Size: 3008 MB    Max Memory Used: 3008 MB
2024-04-08 08:12:55 07 Apr 2024 20:12:55,523 [INFO] (rapid) INVOKE RTDONE(status: success, produced bytes: 0, duration: 62.744000ms)

I managed to solve this by removing WebFlux from my gradle setup.