Issue
I have been trying to replicate this aws function example to deploy a lambda with spring cloud function and graalvm.
The function works locally and starts up without a problem.
❯ ./demo
2021-05-10 15:56:17.964 INFO 10764 --- [ main] o.s.nativex.NativeListener
: This application is bootstrapped with code generated with Spring AOT
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.4.5)
2021-05-10 16:42:42.607 INFO 12792 --- [ main] com.example.demo.DemoApplication : Starting DemoApplication using Java 11.0.11 on loyalty-C02F70R8MD6R with PID 12792 (/Users/user/Workspace/learning/demo/target/demo started by user in /Users/user/Workspace/learning/demo/target)
2021-05-10 16:42:42.607 INFO 12792 --- [ main] com.example.demo.DemoApplication : No active profile set, falling back to default profiles: default
2021-05-10 16:42:42.637 INFO 12792 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
May 10, 2021 4:42:42 PM org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["http-nio-8080"]
May 10, 2021 4:42:42 PM org.apache.catalina.core.StandardService startInternal
INFO: Starting service [Tomcat]
May 10, 2021 4:42:42 PM org.apache.catalina.core.StandardEngine startInternal
INFO: Starting Servlet engine: [Apache Tomcat/9.0.45]
May 10, 2021 4:42:42 PM org.apache.catalina.core.ApplicationContext log
INFO: Initializing Spring embedded WebApplicationContext
2021-05-10 16:42:42.640 INFO 12792 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 32 ms
2021-05-10 16:42:42.650 INFO 12792 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
May 10, 2021 4:42:42 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-nio-8080"]
2021-05-10 16:42:42.658 INFO 12792 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2021-05-10 16:42:42.658 INFO 12792 --- [ main] com.example.demo.DemoApplication : Started DemoApplication in 0.071 seconds (JVM running for 0.072)
However, when I deployed it to aws it failed with the following exception
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.cloud.function.adapter.aws.CustomRuntimeEventLoop': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.cloud.function.adapter.aws.CustomRuntimeEventLoop]: No default constructor found; nested exception is java.lang.NoSuchMethodException: org.springframework.cloud.function.adapter.aws.CustomRuntimeEventLoop.<init>()
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1316) ~[na:na]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1214) ~[na:na]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:564) ~[na:na]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524) ~[na:na]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[na:na]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[na:na]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[na:na]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[na:na]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:944) ~[na:na]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) ~[na:na]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) ~[na:na]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:144) ~[na:na]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:782) ~[demo:na]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:774) ~[demo:na]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439) ~[demo:na]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:339) ~[demo:na]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1340) ~[demo:na]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1329) ~[demo:na]
at com.example.demo.DemoApplication.main(DemoApplication.java:10) ~[demo:na]
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.cloud.function.adapter.aws.CustomRuntimeEventLoop]: No default constructor found; nested exception is java.lang.NoSuchMethodException: org.springframework.cloud.function.adapter.aws.CustomRuntimeEventLoop.<init>()
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:83) ~[na:na]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1308) ~[na:na]
... 18 common frames omitted
Caused by: java.lang.NoSuchMethodException: org.springframework.cloud.function.adapter.aws.CustomRuntimeEventLoop.<init>()
at java.lang.Class.getConstructor0(DynamicHub.java:3349) ~[na:na]
at java.lang.Class.getDeclaredConstructor(DynamicHub.java:2553) ~[na:na]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:78) ~[na:na]
... 19 common frames omitted
I inspected the CustomRuntimeEventLoop and found that class is annotate with
@Configuration
@ConditionalOnProperty("AWS_LAMBDA_RUNTIME_API")
Which means it, only, gets initialised in the AWS environment. And this is why the function did not fail locally. I tried to initialised the class at build time by adding the following snippet to my spring boot application
@NativeHint(initialization = {@InitializationHint(types = {CustomRuntimeEventLoop.class}, initTime = BUILD)})
But this still did not affect the build or runtime behaviour.
Any idea how can I initialise this in the build time?
Solution
Have you seem this example - https://github.com/spring-projects-experimental/spring-native/tree/main/samples/cloud-function-aws?
Also, there were issues with that new CustomRuntimeEventLoop
that have already been addressed, so consider using the latest snapshot.
Answered By - Oleg Zhurakousky
Answer Checked By - Senaida (JavaFixing Volunteer)