Skip to content

IllegalStateException: InputStream has already been read when returning ResponseEntity<InputStreamResource> [SPR-16754] #21295

Closed
@spring-projects-issues

Description

@spring-projects-issues

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:

Referenced from: commits 72cfe41, e9a8a50

Metadata

Metadata

Assignees

Labels

in: webIssues in web modules (web, webmvc, webflux, websocket)type: bugA general bug

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions