- Framework version: 1.3
- Implementations: Spring & Spring Boot
Scenario
At first I was using spring boot with spring profile, and I found that the application has a high possibility to launch twice.
The first launch is fast, and as soon as the log prints out START RequestId:..., the second launch starts.
It may happen at any time during the first launch. The farthest place the first launch can reach from my observation is to print out o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup.
In 10 times of cold start, this issue happens like 8 times. (Yes some times the application do launch once only)
If the application only launches once, it takes ~10s. But for twice, it takes ~40s. The refreshing context for the second launch takes ~10s.
What I mean "launch twice" is that the static init block of SpringBootLambdaContainerHandler was entered twice.
I also tried to declare SpringBootLambdaContainerHandler as a member attribute of MyStreamLambdaHandler, and init it in the constructor. It shows that the constructor was also entered twice.
I thought this can only happen when there's multiple class loaders. So I print out the loader and it's ancestors in the static init block like this:
public class MyStreamLambdaHandler implements RequestStreamHandler {
private static SpringBootLambdaContainerHandler<AwsProxyRequest, AwsProxyResponse> handler;
private static final ClassLoader loader;
static {
try {
loader = Thread.currentThread().getContextClassLoader();
while (loader != null) {
log.info("loader: {}", loader);
loader = loader.getParent();
}
handler = SpringBootLambdaContainerHandler.getAwsProxyHandler(App.class, "develop");
} catch (ContainerInitializationException e) {
// if we fail here. We re-throw the exception to force another cold start
throw new RuntimeException("Could not initialize Spring Boot application", e);
}
}
...
}
The result is here:
First launch:
07:54:33.069 INFO --- [ main] c.w.c.h.c.MyStreamLambdaHandler : loader: java.net.URLClassLoader@5d099f62
07:54:33.070 INFO --- [ main] c.w.c.h.c.MyStreamLambdaHandler : loader: sun.misc.Launcher$AppClassLoader@33909752
07:54:33.070 INFO --- [ main] c.w.c.h.c.MyStreamLambdaHandler : loader: sun.misc.Launcher$ExtClassLoader@66480dd7
Second luanch:
07:54:44.903 INFO --- [ main] c.w.c.h.c.MyStreamLambdaHandler : loader: java.net.URLClassLoader@1d56ce6a
07:54:44.903 INFO --- [ main] c.w.c.h.c.MyStreamLambdaHandler : loader: sun.misc.Launcher$AppClassLoader@33909752
07:54:44.903 INFO --- [ main] c.w.c.h.c.MyStreamLambdaHandler : loader: sun.misc.Launcher$ExtClassLoader@5383967b
As you can see, it's super weird that the same AppClassLoader has different ExtClassLoader as parent...
I also tried to "lazy init" the handler as introduced at #201.
By this way, the application only launches once in handleRequest, but it takes ~30s (~10s for refresh context).
I then tried not to use profile, nothing changed.
I tried to reduced the dependecy and make the application almost the same to demo. The issue still exists.
Finally I found that as long as I'm using spring boot, this issue always happens.
BTW, I found someone who encountered the similar problem at here:
https://forum.serverless.com/t/aws-lambda-coldstart-springboot-booting-2-times/5850
Next, I removed all spring-boot dependecies and used spring only (with profile).
By this way, I got ExceptionInInitializerError directly. The log is here:
07:19:45.637 INFO --- [ main] c.a.s.p.internal.LambdaContainerHandler : Starting Lambda Container Handler
07:19:47.484 INFO --- [ main] c.a.s.p.i.servlet.AwsServletContext : Initializing Spring DispatcherServlet 'aws-servless-java-container'
07:19:47.485 INFO --- [ main] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'aws-servless-java-container'
07:19:47.486 INFO --- [ main] o.s.web.servlet.DispatcherServlet : Completed initialization in 0 ms
07:19:47.487 INFO --- [ main] c.a.s.p.i.servlet.AwsServletContext : Initializing Spring root WebApplicationContext
07:19:47.487 INFO --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization started
07:19:47.487 INFO --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext initialized in 0 ms
07:19:47.777 INFO --- [ main] c.a.s.p.i.servlet.AwsServletContext : Initializing Spring DispatcherServlet 'aws-servless-java-container'
07:19:47.777 INFO --- [ main] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'aws-servless-java-container'
07:19:47.777 INFO --- [ main] o.s.web.servlet.DispatcherServlet : Completed initialization in 0 ms
START RequestId: 7b44e995-1bae-4031-bd24-c2b4c7e6cc31 Version: $LATEST
Error loading class xx.MyStreamLambdaHandler: java.lang.ExceptionInInitializerError
java.lang.ExceptionInInitializerError
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
Caused by: java.lang.IllegalStateException: Cannot initialize context because there is already a root application context present - check whether you have multiple ContextLoader* definitions in your web.xml!
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:262)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:103)
at com.amazonaws.serverless.proxy.spring.LambdaSpringApplicationInitializer.notifyStartListeners(LambdaSpringApplicationInitializer.java:176)
at com.amazonaws.serverless.proxy.spring.LambdaSpringApplicationInitializer.onStartup(LambdaSpringApplicationInitializer.java:170)
at com.amazonaws.serverless.proxy.spring.SpringLambdaContainerHandler.initialize(SpringLambdaContainerHandler.java:192)
at com.amazonaws.serverless.proxy.spring.SpringLambdaContainerHandler.getAwsProxyHandler(SpringLambdaContainerHandler.java:98)
at xx.MyStreamLambdaHandler.<clinit>(MyStreamLambdaHandler.java:22)
... 2 more
END RequestId: 7b44e995-1bae-4031-bd24-c2b4c7e6cc31
REPORT RequestId: 7b44e995-1bae-4031-bd24-c2b4c7e6cc31 Duration: 71.95 ms Billed Duration: 100 ms Memory Size: 1024 MB Max Memory Used: 98 MB
Error loading class xx.MyStreamLambdaHandler
java.lang.ExceptionInInitializerError
07:19:49.209 INFO --- [ main] c.a.s.p.internal.LambdaContainerHandler : Starting Lambda Container Handler
07:19:51.081 INFO --- [ main] c.a.s.p.i.servlet.AwsServletContext : Initializing Spring DispatcherServlet 'aws-servless-java-container'
07:19:51.082 INFO --- [ main] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'aws-servless-java-container'
07:19:51.083 INFO --- [ main] o.s.web.servlet.DispatcherServlet : Completed initialization in 0 ms
07:19:51.096 INFO --- [ main] c.a.s.p.i.servlet.AwsServletContext : Initializing Spring root WebApplicationContext
07:19:51.096 INFO --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization started
07:19:51.096 INFO --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext initialized in 0 ms
07:19:51.458 INFO --- [ main] c.a.s.p.i.servlet.AwsServletContext : Initializing Spring DispatcherServlet 'aws-servless-java-container'
07:19:51.458 INFO --- [ main] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'aws-servless-java-container'
07:19:51.458 INFO --- [ main] o.s.web.servlet.DispatcherServlet : Completed initialization in 0 ms
But if I get rid of profile, the application launches once only.
I looked into the codes, and found that initilizer.onStartup was called twice at newHandler.activateSpringProfiles(profiles) and newHandler.initialize().
I tried to remove L98 and the issue then disappers.
I'm not sure if this fix is correct... Any help is appreciated. I still want to use spring boot with profile but I need to reduced the cold start time.
=============== update
Just confirmed that remove L98 doesn't fix the issue. It happened again.
But this time the stack trace changes:
10:24:49.129 INFO --- [ main] c.a.s.p.internal.LambdaContainerHandler : Starting Lambda Container Handler
10:24:51.107 INFO --- [ main] o.h.validator.internal.util.Version : HV000001: Hibernate Validator 6.0.13.Final
10:24:51.529 INFO --- [ main] c.a.s.p.i.servlet.AwsServletContext : Initializing Spring DispatcherServlet 'aws-servless-java-container'
10:24:51.530 INFO --- [ main] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'aws-servless-java-container'
10:24:51.532 INFO --- [ main] o.s.web.servlet.DispatcherServlet : Completed initialization in 1 ms
10:24:51.532 INFO --- [ main] c.a.s.p.i.servlet.AwsServletContext : Initializing Spring root WebApplicationContext
10:24:51.532 INFO --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization started
10:24:51.533 INFO --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext initialized in 1 ms
START RequestId: 4121d608-9438-4edc-9da9-47a5f90eea70 Version: $LATEST
10:24:52.368 INFO --- [ main] c.a.s.p.i.servlet.AwsServletContext : Initializing Spring DispatcherServlet 'aws-servless-java-container'
10:24:52.369 INFO --- [ main] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'aws-servless-java-container'
10:24:52.369 INFO --- [ main] o.s.web.servlet.DispatcherServlet : Completed initialization in 0 ms
10:24:52.371 ERROR --- [ main] c.a.s.p.internal.LambdaContainerHandler : Error while handling request
java.lang.IllegalStateException: Cannot initialize context because there is already a root application context present - check whether you have multiple ContextLoader* definitions in your web.xml!
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:262)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:103)
at xx.LambdaSpringApplicationInitializer.notifyStartListeners(LambdaSpringApplicationInitializer.java:184)
at xx.LambdaSpringApplicationInitializer.onStartup(LambdaSpringApplicationInitializer.java:178)
at xx.SpringLambdaContainerHandler.initialize(SpringLambdaContainerHandler.java:197)
at xx.SpringLambdaContainerHandler.handleRequest(SpringLambdaContainerHandler.java:180)
at xx.SpringLambdaContainerHandler.handleRequest(SpringLambdaContainerHandler.java:47)
at com.amazonaws.serverless.proxy.internal.LambdaContainerHandler.proxy(LambdaContainerHandler.java:177)
at com.amazonaws.serverless.proxy.internal.LambdaContainerHandler.proxyStream(LambdaContainerHandler.java:209)
at xx.MyStreamLambdaHandler.handleRequest(MyStreamLambdaHandler.java:32)
at lambdainternal.EventHandlerLoader$2.call(EventHandlerLoader.java:888)
at lambdainternal.AWSLambda.startRuntime(AWSLambda.java:293)
at lambdainternal.AWSLambda.<clinit>(AWSLambda.java:64)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at lambdainternal.LambdaRTEntry.main(LambdaRTEntry.java:104)
10:24:52.371 ERROR --- [ main] c.a.s.proxy.AwsProxyExceptionHandler : Called exception handler for:
java.lang.IllegalStateException: Cannot initialize context because there is already a root application context present - check whether you have multiple ContextLoader* definitions in your web.xml!
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:262)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:103)
at xx.LambdaSpringApplicationInitializer.notifyStartListeners(LambdaSpringApplicationInitializer.java:184)
at xx.LambdaSpringApplicationInitializer.onStartup(LambdaSpringApplicationInitializer.java:178)
at xx.SpringLambdaContainerHandler.initialize(SpringLambdaContainerHandler.java:197)
at xx.SpringLambdaContainerHandler.handleRequest(SpringLambdaContainerHandler.java:180)
at xx.SpringLambdaContainerHandler.handleRequest(SpringLambdaContainerHandler.java:47)
at com.amazonaws.serverless.proxy.internal.LambdaContainerHandler.proxy(LambdaContainerHandler.java:177)
at com.amazonaws.serverless.proxy.internal.LambdaContainerHandler.proxyStream(LambdaContainerHandler.java:209)
at xx.MyStreamLambdaHandler.handleRequest(MyStreamLambdaHandler.java:32)
at lambdainternal.EventHandlerLoader$2.call(EventHandlerLoader.java:888)
at lambdainternal.AWSLambda.startRuntime(AWSLambda.java:293)
at lambdainternal.AWSLambda.<clinit>(AWSLambda.java:64)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at lambdainternal.LambdaRTEntry.main(LambdaRTEntry.java:104)
java.lang.IllegalStateException: Cannot initialize context because there is already a root application context present - check whether you have multiple ContextLoader* definitions in your web.xml!
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:262)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:103)
at xx.LambdaSpringApplicationInitializer.notifyStartListeners(LambdaSpringApplicationInitializer.java:184)
at xx.LambdaSpringApplicationInitializer.onStartup(LambdaSpringApplicationInitializer.java:178)
at xx.SpringLambdaContainerHandler.initialize(SpringLambdaContainerHandler.java:197)
at xx.SpringLambdaContainerHandler.handleRequest(SpringLambdaContainerHandler.java:180)
at xx.SpringLambdaContainerHandler.handleRequest(SpringLambdaContainerHandler.java:47)
at com.amazonaws.serverless.proxy.internal.LambdaContainerHandler.proxy(LambdaContainerHandler.java:177)
at com.amazonaws.serverless.proxy.internal.LambdaContainerHandler.proxyStream(LambdaContainerHandler.java:209)
at xx.MyStreamLambdaHandler.handleRequest(MyStreamLambdaHandler.java:32)
at lambdainternal.EventHandlerLoader$2.call(EventHandlerLoader.java:888)
at lambdainternal.AWSLambda.startRuntime(AWSLambda.java:293)
at lambdainternal.AWSLambda.<clinit>(AWSLambda.java:64)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at lambdainternal.LambdaRTEntry.main(LambdaRTEntry.java:104)
END RequestId: 4121d608-9438-4edc-9da9-47a5f90eea70
REPORT RequestId: 4121d608-9438-4edc-9da9-47a5f90eea70 Duration: 882.54 ms Billed Duration: 900 ms Memory Size: 1024 MB Max Memory Used: 112 MB
BTW, I printed the stack trace in the static init block. It's the same for both launches:
07:54:44.880 INFO --- [ main] c.w.c.h.c.MyStreamLambdaHandler : trace: [java.lang.Thread.getStackTrace(Thread.java:1559), xx.MyStreamLambdaHandler.<clinit>(MyStreamLambdaHandler.java:35), java.lang.Class.forName0(Native Method), java.lang.Class.forName(Class.java:348), lambdainternal.HandlerInfo.fromString(HandlerInfo.java:31), lambdainternal.AWSLambda.findUserMethods(AWSLambda.java:93), lambdainternal.AWSLambda.startRuntime(AWSLambda.java:286), lambdainternal.AWSLambda.<clinit>(AWSLambda.java:64), java.lang.Class.forName0(Native Method), java.lang.Class.forName(Class.java:348), lambdainternal.LambdaRTEntry.main(LambdaRTEntry.java:104)]
=============== update
Also needs to initialized = true after initializer.setSpringProfiles(getServletContext(), profiles)
Now the problem disappears again. But it's kinda hard for me to confirm the fix since it's a random issue...
=============== update
If the app is really small (like the demo), then the possibility the issue happens is greatly reduced.
For example, I tried to cold start >10 times, and only get 1 time of problem like this:
03:16:55.234 INFO --- [ main] c.a.s.p.internal.LambdaContainerHandler : Starting Lambda Container Handler
03:16:55.674 INFO --- [ main] c.a.s.p.i.servlet.AwsServletContext : 1 Spring WebApplicationInitializers detected on classpath
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.0.6.RELEASE)
03:16:57.643 INFO 1 --- [ main] xx.MyApp : Starting MyApp on ip-10-128-123-138.ap-southeast-1.compute.internal with PID 1 (/var/task started by sbx_user1060 in /)
03:16:57.645 INFO 1 --- [ main] xx.MyApp : The following profiles are active: develop
03:17:00.626 INFO 1 --- [ main] c.a.s.p.i.servlet.AwsServletContext : Initializing Spring embedded WebApplicationContext
03:17:00.626 INFO 1 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 2751 ms
03:17:01.367 INFO 1 --- [ main] o.s.b.w.servlet.ServletRegistrationBean : Servlet dispatcherServlet mapped to [/]
03:17:01.369 INFO 1 --- [ main] c.a.s.p.i.servlet.AwsServletContext : Initializing Spring DispatcherServlet 'dispatcherServlet'
03:17:01.369 INFO 1 --- [ main] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
03:17:03.221 INFO 1 --- [ main] o.s.web.servlet.DispatcherServlet : Completed initialization in 1821 ms
03:17:03.226 INFO 1 --- [ main] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
03:17:03.226 INFO 1 --- [ main] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'errorPageFilter' to: [/*]
03:17:03.227 INFO 1 --- [ main] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
03:17:03.227 INFO 1 --- [ main] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*]
03:17:03.227 INFO 1 --- [ main] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
START RequestId: 730e90c9-816b-4dc2-a78e-929e0fd19499 Version: $LATEST
03:17:06.004 INFO --- [ main] c.a.s.p.internal.LambdaContainerHandler : Starting Lambda Container Handler
03:17:06.737 INFO --- [ main] c.a.s.p.i.servlet.AwsServletContext : 1 Spring WebApplicationInitializers detected on classpath
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.0.6.RELEASE)
03:17:09.799 INFO 1 --- [ main] xx.MyApp : Starting MyApp on ip-10-128-123-138.ap-southeast-1.compute.internal with PID 1 (/var/task started by sbx_user1060 in /)
03:17:09.813 INFO 1 --- [ main] xx.MyApp : The following profiles are active: develop
03:17:14.163 INFO 1 --- [ main] c.a.s.p.i.servlet.AwsServletContext : Initializing Spring embedded WebApplicationContext
03:17:14.164 INFO 1 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 4200 ms
03:17:15.277 INFO 1 --- [ main] o.s.b.w.servlet.ServletRegistrationBean : Servlet dispatcherServlet mapped to [/]
03:17:15.278 INFO 1 --- [ main] c.a.s.p.i.servlet.AwsServletContext : Initializing Spring DispatcherServlet 'dispatcherServlet'
03:17:15.278 INFO 1 --- [ main] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
03:17:18.022 INFO 1 --- [ main] o.s.web.servlet.DispatcherServlet : Completed initialization in 2744 ms
03:17:18.025 INFO 1 --- [ main] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
03:17:18.041 INFO 1 --- [ main] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'errorPageFilter' to: [/*]
03:17:18.041 INFO 1 --- [ main] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
03:17:18.041 INFO 1 --- [ main] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*]
03:17:18.042 INFO 1 --- [ main] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
03:17:19.238 INFO 1 --- [ main] xx.MyApp : Started MyApp in 11.666 seconds (JVM running for 15.354)
03:17:19.481 INFO 1 --- [ main] c.a.s.p.internal.LambdaContainerHandler : 118.201.58.126 - [02/02/2019:03:16:53Z] "GET /contacts/v1/hello HTTP/1.1" 200 11 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36" combined
END RequestId: 730e90c9-816b-4dc2-a78e-929e0fd19499
REPORT RequestId: 730e90c9-816b-4dc2-a78e-929e0fd19499 Duration: 15336.28 ms Billed Duration: 15400 ms Memory Size: 1024 MB Max Memory Used: 145 MB
START RequestId: 86f22afe-131c-4ae1-8afa-3cccc0234f24 Version: $LATEST
03:26:40.498 INFO 1 --- [ main] c.a.s.p.internal.LambdaContainerHandler : 118.201.58.126 - [02/02/2019:03:26:40Z] "GET /contacts/v1/hello HTTP/1.1" 200 11 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36" combined
END RequestId: 86f22afe-131c-4ae1-8afa-3cccc0234f24
REPORT RequestId: 86f22afe-131c-4ae1-8afa-3cccc0234f24 Duration: 35.07 ms Billed Duration: 100 ms Memory Size: 1024 MB Max Memory Used: 150 MB
Scenario
At first I was using spring boot with spring profile, and I found that the application has a high possibility to launch twice.
The first launch is fast, and as soon as the log prints out
START RequestId:..., the second launch starts.It may happen at any time during the first launch. The farthest place the first launch can reach from my observation is to print out
o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup.In 10 times of cold start, this issue happens like 8 times. (Yes some times the application do launch once only)
If the application only launches once, it takes ~10s. But for twice, it takes ~40s. The refreshing context for the second launch takes ~10s.
What I mean "launch twice" is that the static init block of
SpringBootLambdaContainerHandlerwas entered twice.I also tried to declare
SpringBootLambdaContainerHandleras a member attribute ofMyStreamLambdaHandler, and init it in the constructor. It shows that the constructor was also entered twice.I thought this can only happen when there's multiple class loaders. So I print out the loader and it's ancestors in the static init block like this:
The result is here:
First launch:
Second luanch:
As you can see, it's super weird that the same
AppClassLoaderhas differentExtClassLoaderas parent...I also tried to "lazy init" the handler as introduced at #201.
By this way, the application only launches once in
handleRequest, but it takes ~30s (~10s for refresh context).I then tried not to use profile, nothing changed.
I tried to reduced the dependecy and make the application almost the same to demo. The issue still exists.
Finally I found that as long as I'm using spring boot, this issue always happens.
BTW, I found someone who encountered the similar problem at here:
https://forum.serverless.com/t/aws-lambda-coldstart-springboot-booting-2-times/5850
Next, I removed all spring-boot dependecies and used spring only (with profile).
By this way, I got
ExceptionInInitializerErrordirectly. The log is here:But if I get rid of profile, the application launches once only.
I looked into the codes, and found that
initilizer.onStartupwas called twice at newHandler.activateSpringProfiles(profiles) and newHandler.initialize().I tried to remove L98 and the issue then disappers.
I'm not sure if this fix is correct... Any help is appreciated. I still want to use spring boot with profile but I need to reduced the cold start time.
=============== update
Just confirmed that remove L98 doesn't fix the issue. It happened again.
But this time the stack trace changes:
BTW, I printed the stack trace in the static init block. It's the same for both launches:
=============== update
Also needs to
initialized = trueafter initializer.setSpringProfiles(getServletContext(), profiles)Now the problem disappears again. But it's kinda hard for me to confirm the fix since it's a random issue...
=============== update
If the app is really small (like the demo), then the possibility the issue happens is greatly reduced.
For example, I tried to cold start >10 times, and only get 1 time of problem like this: