java.lang.IllegalStateException: InputStream has already been read - do not use InputStreamResource if a stream needs to be read multiple times

Spring JIRA | Hal Hildebrand | 1 decade ago
tip
Your exception is missing from the Samebug knowledge base.
Here are the best solutions we found on the Internet.
Click on the to mark the helpful solution and get rewards for you help.
  1. 0

    When using an InputStreamResource to create the XmlBeanFactory, an illegal state exception is thrown. java.lang.IllegalStateException: InputStream has already been read - do not use InputStreamResource if a stream needs to be read multiple times at org.springframework.core.io.InputStreamResource.getInputStream(InputStreamResource.java:91) at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.detectValidationMode(XmlBeanDefinitionReader.java:425) at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.getValidationModeForResource(XmlBeanDefinitionReader.java:412) at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.createDocumentBuilderFactory(XmlBeanDefinitionReader.java:385) at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:352) at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:308) at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:283) at org.springframework.beans.factory.xml.XmlBeanFactory.<init>(XmlBeanFactory.java:73) at org.springframework.beans.factory.xml.XmlBeanFactory.<init>(XmlBeanFactory.java:61) at ResourceReadErrorTest.testDoubleRead(ResourceReadErrorTest.java:23) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at com.intellij.rt.execution.junit2.JUnitStarter.main(JUnitStarter.java:32) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:90)

    Spring JIRA | 1 decade ago | Hal Hildebrand
    java.lang.IllegalStateException: InputStream has already been read - do not use InputStreamResource if a stream needs to be read multiple times
  2. 0

    When using an InputStreamResource to create the XmlBeanFactory, an illegal state exception is thrown. java.lang.IllegalStateException: InputStream has already been read - do not use InputStreamResource if a stream needs to be read multiple times at org.springframework.core.io.InputStreamResource.getInputStream(InputStreamResource.java:91) at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.detectValidationMode(XmlBeanDefinitionReader.java:425) at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.getValidationModeForResource(XmlBeanDefinitionReader.java:412) at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.createDocumentBuilderFactory(XmlBeanDefinitionReader.java:385) at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:352) at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:308) at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:283) at org.springframework.beans.factory.xml.XmlBeanFactory.<init>(XmlBeanFactory.java:73) at org.springframework.beans.factory.xml.XmlBeanFactory.<init>(XmlBeanFactory.java:61) at ResourceReadErrorTest.testDoubleRead(ResourceReadErrorTest.java:23) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at com.intellij.rt.execution.junit2.JUnitStarter.main(JUnitStarter.java:32) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:90)

    Spring JIRA | 1 decade ago | Hal Hildebrand
    java.lang.IllegalStateException: InputStream has already been read - do not use InputStreamResource if a stream needs to be read multiple times
  3. 0

    I've been trying to send a multipart post via restTemplate and have been unable to get it to work with anything but FileSystemResource. In my use case (a weird file-forwarding use case) this forces me to copy a MultiPartFile InputStream into a temp file in order be able to create a FileSystemResource, which seems undesirable. Here's a testing version of the file-receiving controller (from another project, running in another servlet container): {code} @RestController public class FileReceiveController { private Log log = LogFactory.getLog(FileReceiveController.class); @RequestMapping(method = RequestMethod.POST) public void uploadFile(@RequestParam("customerId") int customerId, @RequestPart("file") MultipartFile multipartFile) { log.info("customerId: " + customerId); log.info("Received multipart file - original filename: " + multipartFile.getOriginalFilename()); log.info("content-type: " + multipartFile.getContentType()); log.info("size: " + multipartFile.getSize()); } } {code} Here's the file-forwarding controller: {code} @RestController public class FileForwardController { private RestTemplate restTemplate; public FileForwardController() { SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory(); requestFactory.setBufferRequestBody(false); this.restTemplate = new RestTemplate(requestFactory); } @RequestMapping(method = RequestMethod.POST) public void uploadFile(@RequestParam("customerId") int customerId, @RequestPart("file") MultipartFile multipartFile) { MultiValueMap<String,Object> parts = new LinkedMultiValueMap<>(); parts.add("customerId", customerId); try { // copy to temp file and use FileSystemResource // File tempFile = File.createTempFile("xyz", ""); // FileCopyUtils.copy(multipartFile.getInputStream(), new FileOutputStream(tempFile)); // parts.add("file", new FileSystemResource(tempFile)); // OR use InputStreamResource (broken) parts.add("file", new InputStreamResource(multipartFile.getInputStream())); // OR use ByteArrayResource (broken) // parts.add("file", new ByteArrayResource(multipartFile.getBytes())); } catch (IOException e) { throw new RuntimeException(e); } HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.MULTIPART_FORM_DATA); HttpEntity<MultiValueMap<String,Object>> request = new HttpEntity<>(parts, headers); restTemplate.exchange("http://localhost:8080", HttpMethod.POST, request, Void.class); } } {code} In this form, the restTemplate.exchange call throws {code} org.springframework.web.client.HttpClientErrorException: 400 Bad Request at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:91) at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:614) at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:570) {code} The ByteArrayResource form does the same thing. Only the FileSystemResource form works.

    Spring JIRA | 1 year ago | Greg Adams
    java.lang.IllegalStateException: InputStream has already been read - do not use InputStreamResource if a stream needs to be read multiple times
  4. Speed up your debug routine!

    Automated exception search integrated into your IDE

  5. 0

    I've been trying to send a multipart post via restTemplate and have been unable to get it to work with anything but FileSystemResource. In my use case (a weird file-forwarding use case) this forces me to copy a MultiPartFile InputStream into a temp file in order be able to create a FileSystemResource, which seems undesirable. Here's a testing version of the file-receiving controller (from another project, running in another servlet container): {code} @RestController public class FileReceiveController { private Log log = LogFactory.getLog(FileReceiveController.class); @RequestMapping(method = RequestMethod.POST) public void uploadFile(@RequestParam("customerId") int customerId, @RequestPart("file") MultipartFile multipartFile) { log.info("customerId: " + customerId); log.info("Received multipart file - original filename: " + multipartFile.getOriginalFilename()); log.info("content-type: " + multipartFile.getContentType()); log.info("size: " + multipartFile.getSize()); } } {code} Here's the file-forwarding controller: {code} @RestController public class FileForwardController { private RestTemplate restTemplate; public FileForwardController() { SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory(); requestFactory.setBufferRequestBody(false); this.restTemplate = new RestTemplate(requestFactory); } @RequestMapping(method = RequestMethod.POST) public void uploadFile(@RequestParam("customerId") int customerId, @RequestPart("file") MultipartFile multipartFile) { MultiValueMap<String,Object> parts = new LinkedMultiValueMap<>(); parts.add("customerId", customerId); try { // copy to temp file and use FileSystemResource // File tempFile = File.createTempFile("xyz", ""); // FileCopyUtils.copy(multipartFile.getInputStream(), new FileOutputStream(tempFile)); // parts.add("file", new FileSystemResource(tempFile)); // OR use InputStreamResource (broken) parts.add("file", new InputStreamResource(multipartFile.getInputStream())); // OR use ByteArrayResource (broken) // parts.add("file", new ByteArrayResource(multipartFile.getBytes())); } catch (IOException e) { throw new RuntimeException(e); } HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.MULTIPART_FORM_DATA); HttpEntity<MultiValueMap<String,Object>> request = new HttpEntity<>(parts, headers); restTemplate.exchange("http://localhost:8080", HttpMethod.POST, request, Void.class); } } {code} In this form, the restTemplate.exchange call throws {code} org.springframework.web.client.HttpClientErrorException: 400 Bad Request at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:91) at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:614) at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:570) {code} The ByteArrayResource form does the same thing. Only the FileSystemResource form works.

    Spring JIRA | 1 year ago | Greg Adams
    java.lang.IllegalStateException: InputStream has already been read - do not use InputStreamResource if a stream needs to be read multiple times

    Root Cause Analysis

    1. java.lang.IllegalStateException

      InputStream has already been read - do not use InputStreamResource if a stream needs to be read multiple times

      at org.springframework.core.io.InputStreamResource.getInputStream()
    2. Spring Core
      InputStreamResource.getInputStream
      1. org.springframework.core.io.InputStreamResource.getInputStream(InputStreamResource.java:91)
      1 frame
    3. Spring Beans
      XmlBeanFactory.<init>
      1. org.springframework.beans.factory.xml.XmlBeanDefinitionReader.detectValidationMode(XmlBeanDefinitionReader.java:425)
      2. org.springframework.beans.factory.xml.XmlBeanDefinitionReader.getValidationModeForResource(XmlBeanDefinitionReader.java:412)
      3. org.springframework.beans.factory.xml.XmlBeanDefinitionReader.createDocumentBuilderFactory(XmlBeanDefinitionReader.java:385)
      4. org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:352)
      5. org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:308)
      6. org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:283)
      7. org.springframework.beans.factory.xml.XmlBeanFactory.<init>(XmlBeanFactory.java:73)
      8. org.springframework.beans.factory.xml.XmlBeanFactory.<init>(XmlBeanFactory.java:61)
      8 frames
    4. Unknown
      ResourceReadErrorTest.testDoubleRead
      1. ResourceReadErrorTest.testDoubleRead(ResourceReadErrorTest.java:23)
      1 frame
    5. Java RT
      DelegatingMethodAccessorImpl.invoke
      1. sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      2. sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      3. sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      3 frames
    6. com.intellij.rt
      JUnitStarter.main
      1. com.intellij.rt.execution.junit2.JUnitStarter.main(JUnitStarter.java:32)
      1 frame
    7. Java RT
      DelegatingMethodAccessorImpl.invoke
      1. sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      2. sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      3. sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      3 frames
    8. IDEA
      AppMain.main
      1. com.intellij.rt.execution.application.AppMain.main(AppMain.java:90)
      1 frame