The same code is working using version 2.x.x. The combination of @Async methods and ContextHolders inside these async methods returns the following error in version 3.x.x of spring boot.
Code:
Another example (using interceptor):
Code:
Application Thread Inheritarable configuration
Comment From: scottfrederick
Thanks for getting in touch. Unfortunately, you haven't provided enough information for us to be able to help you. If you would like us to spend some time investigating, please provide a complete minimal sample that reproduces the problem. You can share it with us by pushing it to a separate repository on GitHub or by zipping it and attaching it to this issue.
Comment From: luizimcpi
Oh sorry , i´ve created a repo here in github that reproduces the problem. spring-async-context-issue
Comment From: StareStarrySky
the method org.apache.catalina.connector.RequestFacade.clear(RequestFacade.java:227) called when 3.1.2, but 2.7.14 not. What's going on?
Comment From: wilkinsona
You are relying upon the request still be usable after its handling has completed which may not work reliably. You got away with it with Spring Boot 2.7 and Tomcat 9.x as Tomcat 9.x is less aggressive in its clean up when a request completes. This default changed in Tomcat 10.
You will experience the same failure with Tomcat 9.x if you set the org.apache.catalina.connector.RECYCLE_FACADES system property to true:
java.lang.IllegalStateException: The request object has been recycled and is no longer associated with this facade
at org.apache.catalina.connector.RequestFacade.checkFacade(RequestFacade.java:857) ~[tomcat-embed-core-9.0.78.jar:9.0.78]
at org.apache.catalina.connector.RequestFacade.getLocale(RequestFacade.java:426) ~[tomcat-embed-core-9.0.78.jar:9.0.78]
at org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver.resolveLocale(AcceptHeaderLocaleResolver.java:102) ~[spring-webmvc-5.3.29.jar:5.3.29]
at org.springframework.web.servlet.DispatcherServlet.lambda$buildLocaleContext$3(DispatcherServlet.java:1186) ~[spring-webmvc-5.3.29.jar:5.3.29]
at org.springframework.context.i18n.LocaleContextHolder.getLocale(LocaleContextHolder.java:224) ~[spring-context-5.3.29.jar:5.3.29]
at org.springframework.context.i18n.LocaleContextHolder.getLocale(LocaleContextHolder.java:205) ~[spring-context-5.3.29.jar:5.3.29]
at io.github.luizimcpi.asynccontext.service.CarsService.processCarsByLanguage(CarsService.java:27) ~[classes/:na]
at io.github.luizimcpi.asynccontext.service.CarsService$$FastClassBySpringCGLIB$$53476055.invoke(<generated>) ~[classes/:na]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.3.29.jar:5.3.29]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:793) ~[spring-aop-5.3.29.jar:5.3.29]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.3.29.jar:5.3.29]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) ~[spring-aop-5.3.29.jar:5.3.29]
at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:115) ~[spring-aop-5.3.29.jar:5.3.29]
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) ~[na:na]
at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]
You should update your application so that it does not try to use state from the request in any processing that is done asynchronously.
Alternatively, and I do not recommend this approach, you can configure Tomcat 10.x not to discard the facade:
@Bean
TomcatConnectorCustomizer disableFacadeDiscard() {
return (connector) -> connector.setDiscardFacades(false);
}
Comment From: luizimcpi
Ok, thanks @wilkinsona !
Comment From: ar11arpitp
You are relying upon the request still be usable after its handling has completed which may not work reliably. You got away with it with Spring Boot 2.7 and Tomcat 9.x as Tomcat 9.x is less aggressive in its clean up when a request completes. This default changed in Tomcat 10.
You will experience the same failure with Tomcat 9.x if you set the
org.apache.catalina.connector.RECYCLE_FACADESsystem property totrue:
java.lang.IllegalStateException: The request object has been recycled and is no longer associated with this facade at org.apache.catalina.connector.RequestFacade.checkFacade(RequestFacade.java:857) ~[tomcat-embed-core-9.0.78.jar:9.0.78] at org.apache.catalina.connector.RequestFacade.getLocale(RequestFacade.java:426) ~[tomcat-embed-core-9.0.78.jar:9.0.78] at org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver.resolveLocale(AcceptHeaderLocaleResolver.java:102) ~[spring-webmvc-5.3.29.jar:5.3.29] at org.springframework.web.servlet.DispatcherServlet.lambda$buildLocaleContext$3(DispatcherServlet.java:1186) ~[spring-webmvc-5.3.29.jar:5.3.29] at org.springframework.context.i18n.LocaleContextHolder.getLocale(LocaleContextHolder.java:224) ~[spring-context-5.3.29.jar:5.3.29] at org.springframework.context.i18n.LocaleContextHolder.getLocale(LocaleContextHolder.java:205) ~[spring-context-5.3.29.jar:5.3.29] at io.github.luizimcpi.asynccontext.service.CarsService.processCarsByLanguage(CarsService.java:27) ~[classes/:na] at io.github.luizimcpi.asynccontext.service.CarsService$$FastClassBySpringCGLIB$$53476055.invoke(<generated>) ~[classes/:na] at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.3.29.jar:5.3.29] at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:793) ~[spring-aop-5.3.29.jar:5.3.29] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.3.29.jar:5.3.29] at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) ~[spring-aop-5.3.29.jar:5.3.29] at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:115) ~[spring-aop-5.3.29.jar:5.3.29] at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[na:na] at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) ~[na:na] at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) ~[na:na] at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]You should update your application so that it does not try to use state from the request in any processing that is done asynchronously.
Alternatively, and I do not recommend this approach, you can configure Tomcat 10.x not to discard the facade:
@Bean TomcatConnectorCustomizer disableFacadeDiscard() { return (connector) -> connector.setDiscardFacades(false); }
Hi, I am using Spring boot 3.1.6 with tomcat 10.x but i am stilling getting the below error
Java.lang.IllegalStateException: The request object has been recycled and is no longer associated with this facade at org.apache.catalina.connector.RequestFacade.checkFacade(RequestFacade.java:855) at org.apache.catalina.connector.RequestFacade.getHeader(RequestFacade.java:505) at jakarta.servlet.http.HttpServletRequestWrapper.getHeader(HttpServletRequestWrapper.java:82) at org.springframework.security.web.firewall.StrictHttpFirewall$StrictFirewalledRequest.getHeader(StrictHttpFirewall.java:714)
I my case i have 2 async method calls which giving this error
Comment From: wilkinsona
@ar11arpitp you haven't provided enough information for us to know exactly what the problem is. Please open a new issue with a minimal example that reproduces the problem and we can take another look.
Comment From: reizy
Hi, I am using Spring boot 3.1.6 with tomcat 10.x but i am stilling getting the below error
@ar11arpitp, "You should update your application" means "You should change your application". not "update dependencies" As I understand you shouldn't read any request fields in FutureTask