Code Monkey home page Code Monkey logo

Comments (12)

deki avatar deki commented on June 12, 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.

from serverless-java-container.

jeusdi avatar jeusdi commented on June 12, 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?

from serverless-java-container.

deki avatar deki commented on June 12, 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

from serverless-java-container.

jeusdi avatar jeusdi commented on June 12, 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

from serverless-java-container.

deki avatar deki commented on June 12, 2024

@olegz can you look into this one?

from serverless-java-container.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.