Would appreciate any help regarding my issue on one of my maven projects.
Exception in thread "main" org.springframework.web.client.ResourceAccessException: I/O error on POST request for "https://test-services.domain.ph/campaign/": Premature EOF; nested exception is java.io.IOException: Premature EOF
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:666)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:613)
at org.springframework.web.client.RestTemplate.postForEntity(RestTemplate.java:407)
at homecredit.ph.CampaignConnector.call(CampaignConnector.java:46)
Caused by: java.io.IOException: Premature EOF
at sun.net.www.http.ChunkedInputStream.readAheadBlocking(ChunkedInputStream.java:565)
at sun.net.www.http.ChunkedInputStream.readAhead(ChunkedInputStream.java:609)
at sun.net.www.http.ChunkedInputStream.read(ChunkedInputStream.java:696)
at java.io.FilterInputStream.read(FilterInputStream.java:133)
Origin:
ResponseEntity<ApiResponse> response = restTemplate.postForEntity(url, entity, ApiResponse.class);
Destination:
#RequestMapping(value="/campaign", method = RequestMethod.POST, consumes=MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<ApiResponse> insertCampaignRecord(
#Valid #RequestBody CampaignRecordInsertRequest campaignRecordInsertRequest){
logInfo("Incoming insert request. " + DescriptorUtility.convertToString(campaignRecordInsertRequest));
campaignDataService.insertNewRecord(CampaignRecordConverter.convertToCampaignRecord(campaignRecordInsertRequest));
return ResponseUtility.defaultResponse();
}
ResponseUtility
public static ResponseEntity<ApiResponse> defaultResponse(){
ApiResponse apiResponse = new ApiResponse();
apiResponse.setTimestamp(DateUtility.currentDateString());
apiResponse.setMessage(ResponseMessages.SUCCESS);
return new ResponseEntity<>(apiResponse, HttpStatus.OK);
}
CampaignData Service
#Async("AsyncExecutor")
public void insertNewRecord(CampaignRecord campaignRecord) {
try {
campaignRecordRepository.save(campaignRecord);
} catch (Exception e) {
logError(e);
}
}
Server Log
2017-09-11 11:11:11 INFO 18383 [http-nio-8773-exec-10] [CampaignRecordController] - Incoming insert request. {"dateCampaign":1504656000000,"cuid":...
2017-09-11 11:11:11 WARN 18383 [http-nio-8773-exec-10] [SqlExceptionHelper] - SQL Error: 1062, SQLState: 23000
2017-09-11 11:11:11 ERROR 18383 [http-nio-8773-exec-10] [SqlExceptionHelper] - Duplicate entry 'CMP_CLX##1208637#20170906' for key 'UNIQUE_KEY'
2017-09-11 11:11:11 ERROR 18383 [http-nio-8773-exec-10] [CampaignDataService] - could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
2017-09-11 11:11:11 ERROR 18383 [http-nio-8773-exec-10] [CampaignDataService] - could not execute statement
PS. Server logs is normal(return a successful response either record successfully saved or not)
Issue is intermittent. Occurs randomly when sending bulk requests.
Thanks in advance! :)
I had the same problem in Spring Boot 2.1. In my case I had 3 apps (call them A, B, and C) where B was really just a proxy between A and C:
A --> B --> C
The Premature EOF was occurring on the response from B to A. All indications were a successful HTTP response (200), but inspecting the body of the response using a debugger revealed it had a new line character in the middle of the serialized DTO data, instead of at the end where I expected it:
(Notice the return character after the id field, and lack of any content length; ignore the unreadable boxes at the end, they're part of the byte array that are not initialized/used)
In my case, Service B is both a server and a client. The code looked something like this:
public ResponseEntity<String> handle(String request, HttpHeaders headers) {
// Do some validation and then call Service C, and pass the response
// back to Service A
return restTemplate.postForEntity(
urlForServiceC,
new HttpEntity<>(request, headers),
String.class);
}
I didn't dive too far into the guts of RestTemplate or its message converters, but what tipped me off that there might be an issue with the response buffering is that I was using a Spring filter to log the responses of each service. This filter has to copy the response stream to avoid exceptions from other filters related to the body already being consumed.
What I noticed is that when I ran with this filter enabled, the Premature EOF exceptions went away. And when I disabled it, the exceptions came back. Something about copying the response stream had solved the Premature EOF errors.
This led me to try the following in Service B:
public ResponseEntity<String> handle(String request, HttpHeaders headers) {
// Do some validation and then call Service C, and pass the response
// back to Service A
String response = restTemplate.postForEntity(
urlForServiceC,
new HttpEntity<>(request, headers),
String.class).getBody();
return ResponseEntity.ok(response);
}
The subtle change is that I'm saving the response first to a local variable, which requires me to call ResponseEntity.getBody(). This forces the entire response body from Service C to be consumed before returning to Service A. After making this change my Premature EOF errors have not returned.
Based on the server logs seems like, the server is trying save some record and its failing (due to Unique key violation).
2017-09-11 11:11:11 WARN 18383 [http-nio-8773-exec-10] [SqlExceptionHelper] - SQL Error: 1062, SQLState: 23000
2017-09-11 11:11:11 ERROR 18383 [http-nio-8773-exec-10] [SqlExceptionHelper] - Duplicate entry 'CMP_CLX##1208637#20170906' for key 'UNIQUE_KEY'
2017-09-11 11:11:11 ERROR 18383 [http-nio-8773-exec-10] [CampaignDataService] - could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
2017-09-11 11:11:11 ERROR 18383 [http-nio-8773-exec-10] [CampaignDataService] - could not execute statement
Looks like the server is not able to handle the exception gracefully and the whole flow breaks, causing a HTTP-500 response code (probably) with an empty response.
Two actions you can take:
Handle the exception gracefully.
Verify why unique key is getting violated and fix that if possible.
For anyone who might be experiencing this.
Issue was caused by spring boot eureka.
Seems like there is a bug when it comes to passing ResponseEntity response in a massive scale (bulk processing) that causes the response status to be malformed.
Current workaround is to switch from ResponseEntity to the object body instead.
I have the same problem when i use RestTemplate with default http client factory.I found it missing 'Accept-Encoding:gzip' in the headers when I capture packets.Finally i get it by replace the default http client factory with apache's http client factory,like this:
HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(HttpClientBuilder.create().build());
RestTemplate restTemplate = new RestTemplate(clientHttpRequestFactory);
Related
I am using microservice architecture, when trying to upload a larger file(<100 MB) in a post-request body, post call is failing.
There are 2 scenarios in my case:
Scenerio I : When I am going via API Gateway getting the below exception.
2023-01-13 19:57:07 [index:api-gateway] ERROR [tId:b877e870-2311-4561-9f31-6969cb52d6e3] [rId:641014c9-abfb-4343-8fd6-290f465e7cb9] : Filter threw Exception
com.netflix.zuul.exception.ZuulException: Filter threw Exception
at com.netflix.zuul.FilterProcessor.processZuulFilter(FilterProcessor.java:227)
... 40 common frames omitted
Caused by: org.apache.http.client.NonRepeatableRequestException: Cannot retry request with a non-repeatable request entity
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:108)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
... 44 common frames omitted
Caused by: java.net.SocketException: Connection reset
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:115)
at java.net.SocketOutputStream.write(SocketOutputStream.java:155)
at sun.security.ssl.SSLSocketOutputRecord.deliver(SSLSocketOutputRecord.java:319)
at sun.security.ssl.SSLSocketImpl$AppOutputStream.write(SSLSocketImpl.java:1188)
Scenerio II : And when directly calling my microservice getting below error:
413 : Request Entity Too Large
Here is my controller:
#PostMapping("load/largefile")
public ResponseObj loadHaevyFileToS3(#RequestParam(value = "file") MultipartFile jsonDataFile) {
return new ResponseObj(true,loadService.load(jsonDataFile));
}
I have added the below properties in application.properties and Spring version is : 5.0.8.RELEASE
spring.servlet.multipart.enabled=true
spring.servlet.multipart.max-request-size=300MB
spring.servlet.multipart.max-file-size=300MB
Whats wrong I am doing here?
I am trying to solve a very puzzling error. I have the following code executing an HTTP Post to a remove server.
httpPost.setEntity(new StringEntity(requestAsString));
HttpResponse httpResponse = httpClient.execute(httpHost, httpPost);
Arrays.asList(httpResponse.getAllHeaders()).stream().forEach(header -> System.out.println(header.getName() + " : " + header.getValue()));
Thread.sleep(10_000);
List<DataRecord> value = Arrays.asList(objectMapper.readValue(httpResponse.getEntity().getContent(), DataRecord[].class));
The response is ~63Mb and this only happens with large responses. When I run this code I get the following error:
com.fasterxml.jackson.databind.JsonMappingException: Premature end of Content-Length delimited message body (expected: 63476765; received: 404420 (through reference chain: java.lang.Object[][1189])
at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:391)
at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:363)
at com.fasterxml.jackson.databind.deser.std.ObjectArrayDeserializer.deserialize(ObjectArrayDeserializer.java:206)
at com.fasterxml.jackson.databind.deser.std.ObjectArrayDeserializer.deserialize(ObjectArrayDeserializer.java:21)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4001)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3058)
at com.company.Class1.queryData(Class1.java:74)
... 5 more
Caused by: org.apache.http.ConnectionClosedException: Premature end of Content-Length delimited message body (expected: 63476765; received: 404420
at org.apache.http.impl.io.ContentLengthInputStream.read(ContentLengthInputStream.java:178)
at org.apache.http.conn.EofSensorInputStream.read(EofSensorInputStream.java:135)
at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._loadMore(UTF8StreamJsonParser.java:205)
at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._parseFloat(UTF8StreamJsonParser.java:1524)
at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._parsePosNumber(UTF8StreamJsonParser.java:1363)
at com.fasterxml.jackson.core.json.UTF8StreamJsonParser.nextFieldName(UTF8StreamJsonParser.java:1025)
at com.fasterxml.jackson.databind.deser.std.MapDeserializer._readAndBind(MapDeserializer.java:448)
at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:367)
at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:29)
at com.fasterxml.jackson.databind.deser.impl.FieldProperty.deserializeAndSet(FieldProperty.java:136)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:288)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:151)
at com.fasterxml.jackson.databind.deser.std.ObjectArrayDeserializer.deserialize(ObjectArrayDeserializer.java:195)
However, this error does not happen if I remove
Thread.sleep(10_000);
If the issue was that the client was not getting the full response from the server, I would expect to see the problem exist even if I did not have the Thread sleep in there. The issue also will go away if I shorten the Thread.sleep(...) to only 5 seconds. It seems as though it's a time problem, but since I already have the HttpResponse object before I call Thread.sleep(...), I can't find anything that could be timing out. Any help with this issue is appreciated.
Stack:AngularJS v1.6.5, java 8, spring boot, tomcat.
After about 1 week of work , the application not response with such an error. Why this happening?
Frontend:
$http({
url: 'find',
method: "post",
data: { 'month' : $scope.month,'year' : $scope.year, 'payTime' : $scope.payTime,'waitTime' : $scope.waitTime,'scanTime' : $scope.scanTime,'gbNumber' : $scope.hyper}
})
.then(function(response) {
..
});
}
Backend:
#RequestMapping(path = "/find", method = RequestMethod.POST)
public ReportResponse find(#RequestBody RequestSearch params,
HttpServletResponse response) throws DataNotFoundException {
...
}
Stacktrace:
2018-04-02 09:37:44.738 ERROR 14912 --- [p-nio-80-exec-9] o.s.boot.web.support.ErrorPageFilter : Cannot forward to error page for request [/excel/ExceReport.xls] as the response has already been committed. As a result, the response may have the wrong status code. If your application is running on WebSphere Application Server you may be able to resolve this problem by setting com.ibm.ws.webcontainer.invokeFlushAfterService to false
org.apache.catalina.connector.ClientAbortException: java.io.IOException: An established connection was aborted by the software in your host machine
at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:356) ~[catalina.jar:8.5.24]
at org.apache.catalina.connector.OutputBuffer.flushByteBuffer(OutputBuffer.java:815) ~[catalina.jar:8.5.24]
at org.apache.catalina.connector.OutputBuffer.append(OutputBuffer.java:720) ~[catalina.jar:8.5.24]
at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:391) ~[catalina.jar:8.5.24]
at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:369) ~[catalina.jar:8.5.24]
at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:96) ~[catalina.jar:8.5.24]
at org.springframework.util.StreamUtils.copy(StreamUtils.java:138) ~[spring-core-4.3.9.RELEASE.jar:4.3.9.RELEASE]
at org.springframework.http.converter.ResourceHttpMessageConverter.writeContent(ResourceHttpMessageConverter.java:110) ~[spring-web-4.3.9.RELEASE.jar:4.3.9.RELEASE]
at org.springframework.http.converter.ResourceHttpMessageConverter.writeInternal(ResourceHttpMessageConverter.java:102) ~[spring-web-4.3.9.RELEASE.jar:4.3.9.RELEASE]
...
Cause
This exception can mean that the connection to the client browser was
aborted before the response is fully transferred. It is a harmless
warning as it can be due to transient network problems or the user
aborts/refreshes the page before it loaded.
A list of other causes are:
The user closed the browser before the page loaded.
Their Internet connection failed during loading.
They went to another page before the page loaded.
The browser timed the connection out before the page loaded (would
have to be a large page).
Resolution
This can be ignored, unless there are other issues that are currently
occurring. For example, if the your application server is throwing a
lot of these, it might be a sign of a performance problem.
I use SpringBoot and Jersey into my project and I often tackle the following error :
[ERROR - ServerRuntime$Responder - 2018-02-13 13:16:45,983] An I/O error has occurred while writing a response message entity to the container output stream.
org.glassfish.jersey.server.internal.process.MappableException: org.apache.catalina.connector.ClientAbortException: java.io.IOException: Broken pipe
at org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor.aroundWriteTo(MappableExceptionWrapperInterceptor.java:92)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162)
at org.glassfish.jersey.message.internal.MessageBodyFactory.writeTo(MessageBodyFactory.java:1130)
at org.glassfish.jersey.server.ServerRuntime$Responder.writeResponse(ServerRuntime.java:711)
at org.glassfish.jersey.server.ServerRuntime$Responder.processResponse(ServerRuntime.java:444)
at org.glassfish.jersey.server.ServerRuntime$Responder.process(ServerRuntime.java:434)
at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:329)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
It results with a 503 status response to my client.
Could you explain me why this error occured ?
Thanks
This kind of error usually happens servlet is writing data back on the stream and connection closed from client side.
It is like server in sending some data may be file, string, bytes etc.. but on client side like a browser has closed the connection, like you close the browser tab.
It cased early End of file exception on the server.
I have had this exception when I accidentally passed a null Response at the end of a call. You can verify this in the'caused by' section following the first exception:
Caused by: org.eclipse.jetty.io.EofException: null
I am getting the below error while running through linux script. This is not happening always sometimes it succeeded and sometimes the below error.:
org.springframework.web.client.HttpServerErrorException: 500 Internal
Server Error
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:78)
at org.springframework.web.client.RestTemplate.handleResponseError(RestTemplate.java:486)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:443)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:401)
at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:199)
at com.gtech.lsp.utils.SynchronizeRetailerData.main(SynchronizeRetailerData.java:42)
Exception in thread "main"
org.springframework.web.client.HttpServerErrorException: 500 Internal
Server Error
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:78)
at org.springframework.web.client.RestTemplate.handleResponseError(RestTemplate.java:486)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:443)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:401)
at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:199)
I am initializing the RestTemplate as below:
url = PreferencesUtil.getInstance().getAppRoot()
.get("lsp.sync.retailer.url", "http://localhost:8080/lsptx/public/syncRetailer");
restTemplate = new RestTemplate();
restTemplate.getForObject(url, String.class, jurId);
could you please help me on this?