Closed
Description
Jessy James opened SPR-16754 and commented
With the recent upgrade to Spring-Boot-2, also Spring-5 came in and I guess it is related to the upgrade from 4 to 5. So here's the issue. I have a controller which provides a download for the user by returning a ResponseEntity<InputStreamResource>. After the recent upgrade I now see frequently these errors in the log:
Apr 22 01:40:00 ru downloader.jar[7010]: 2018-04-22 01:40:00.083 ERROR 7030 --- [p-nio-80-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.IllegalStateException: InputStream has already been read - do not use InputStreamResource if a stream needs to be read multiple times] with root cause
Apr 22 01:40:00 ru downloader.jar[7010]: java.lang.IllegalStateException: InputStream has already been read - do not use InputStreamResource if a stream needs to be read multiple times
Apr 22 01:40:00 ru downloader.jar[7010]: at org.springframework.core.io.InputStreamResource.getInputStream(InputStreamResource.java:97)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.springframework.http.converter.ResourceHttpMessageConverter.writeContent(ResourceHttpMessageConverter.java:130)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.springframework.http.converter.ResourceHttpMessageConverter.writeInternal(ResourceHttpMessageConverter.java:124)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.springframework.http.converter.ResourceHttpMessageConverter.writeInternal(ResourceHttpMessageConverter.java:45)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.springframework.http.converter.AbstractHttpMessageConverter.write(AbstractHttpMessageConverter.java:224)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:274)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor.handleReturnValue(HttpEntityMethodProcessor.java:224)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:82)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:119)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:877)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:783)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:866)
Apr 22 01:40:00 ru downloader.jar[7010]: at javax.servlet.http.HttpServlet.service(HttpServlet.java:635)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851)
Apr 22 01:40:00 ru downloader.jar[7010]: at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.springframework.web.servlet.resource.ResourceUrlEncodingFilter.doFilter(ResourceUrlEncodingFilter.java:60)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics(WebMvcMetricsFilter.java:158)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics(WebMvcMetricsFilter.java:126)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:111)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.springframework.boot.actuate.web.trace.servlet.HttpTraceFilter.doFilterInternal(HttpTraceFilter.java:84)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:496)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
Apr 22 01:40:00 ru downloader.jar[7010]: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
Apr 22 01:40:00 ru downloader.jar[7010]: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
Apr 22 01:40:00 ru downloader.jar[7010]: at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
Apr 22 01:40:00 ru downloader.jar[7010]: at java.lang.Thread.run(Thread.java:748)
I tried some scenarios locally and couldn't reproduce it. Also it happens not all the time, just sometimes it fails in said ways. The stack trace doesn't contain anything from my code. With Spring-Boot-1 I never had those errors.
This is an exemplary extract of my Controller:
@RequestMapping(method = RequestMethod.GET)
public ResponseEntity<InputStreamResource> download(@ModelAttribute("providerId") String providerId,
@ModelAttribute("slug") String slug, HttpServletRequest request)
throws IOException, SomeOfMyExceptions {
// ...
BodyBuilder builder = null; // Nice class name,
if (isPartial) {
builder = status(PARTIAL_CONTENT);
builder.header("Content-Range", range);
} else {
builder = ok();
if (acceptsRange) {
builder.header("Accept-Ranges", "bytes");
} else {
builder.header("Accept-Ranges", "none");
}
}
builder.contentType(contentType);
download.contentLength().ifPresent(builder::contentLength);
download.etag().ifPresent(builder::eTag);
download.lastModified().ifPresent(builder::lastModified);
builder.header("Content-Disposition", String.format("attachment; filename=\"%s\"", filename));
return builder.body(new InputStreamResource(stream));
}
Affects: 5.0.5
Reference URL: spring-projects/spring-boot#12939
Issue Links:
- AbstractMessageConverterMethodProcessor doesn't respect already handled headers and result-codes [SPR-16921] #21460 AbstractMessageConverterMethodProcessor doesn't respect already handled headers and result-codes