Arjen Poutsma opened SPR-7909 and commented
When sending a large file with the RestTemplate (with a POST or PUT), the RestTemplate will throw an OutOfMemoryError:
com.cat.tcm.jmx.ManagementException: An unexpected error occurred performing the operation.
at com.cat.tcm.jmx.JMXTaskTemplate.run(JMXTaskTemplate.java:144)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)
Caused by: java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:2786)
at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:94)
at org.springframework.util.FileCopyUtils.copy(FileCopyUtils.java:113)
at org.springframework.http.converter.ResourceHttpMessageConverter.write(ResourceHttpMessageConverter.java:85)
at org.springframework.http.converter.ResourceHttpMessageConverter.write(ResourceHttpMessageConverter.java:1)
at org.springframework.http.converter.FormHttpMessageConverter.writePart(FormHttpMessageConverter.java:288)
at org.springframework.http.converter.FormHttpMessageConverter.writeParts(FormHttpMessageConverter.java:252)
at org.springframework.http.converter.FormHttpMessageConverter.writeMultipart(FormHttpMessageConverter.java:242)
at org.springframework.http.converter.FormHttpMessageConverter.write(FormHttpMessageConverter.java:194)
at org.springframework.http.converter.FormHttpMessageConverter.write(FormHttpMessageConverter.java:1)
at org.springframework.web.client.RestTemplate$HttpEntityRequestCallback.doWithRequest(RestTemplate.java:588)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:436)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:401)
at org.springframework.web.client.RestTemplate.postForObject(RestTemplate.java:279)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:50)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at $Proxy17.postForObject(Unknown Source)
Issue Links: - INT-2006 http:inbound-gateway/outbound-gateway content-length needs recalculation
Referenced from: commits https://github.com/spring-projects/spring-framework/commit/d0d6a07870ff39a3441249a66ce860eb972f6891, https://github.com/spring-projects/spring-framework/commit/1ed1c59888c8cf676e3767c41af9370616a3ed7b
Comment From: spring-projects-issues
Arjen Poutsma commented
This is due to the fact that we buffer all content before sending it over the wire, which is necessary for setting the correct Content-Length header.
Comment From: spring-projects-issues
Arjen Poutsma commented
Fixed, by adding a 'bufferRequestBody' property to the SimpleClientHttpRequestFactory, which by default is true.
Setting this property to false will enable streaming mode. This will result in a ClientHttpRequest that either streams directly to the underlying HttpURLConnection (if the Content-Length is known in advance), or that will use "Chunked transfer encoding" (if the Content-Length is not known in advance). That is:
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
requestFactory.setBufferRequestBody(false);
RestTemplate rest = new RestTemplate(requestFactory);
These changes will be in 3.0.6, and in 3.1 M1. Please try a recent 3.1 M1 (as of tonight) to see if it works for you.
Comment From: spring-projects-issues
Juergen Hoeller commented
I've removed this from the 3.0.6 backport list since it really seems to be a new 3.1 feature to me. Unless there is a strong need to have this in 3.0.x, I'd rather recommend an upgrade to 3.1 instead.
Juergen
Comment From: spring-projects-issues
Serge P. Nekoval commented
Any chance to get it fixed for HttpComponentsClientHttpRequestFactory?
Comment From: ghost
How to add this property with feign instead of restTemplate?
Comment From: SauriBabu
@poutsma can you help me with below confusions. How to set content-length ? using HttpHeaders ? How much should be content-length ? Should it be equal to fileSize or byte size by which we want to buffer ?