5

I'm getting similar error to this link1. When I post(client to server) a small xml via REST, everything works fine. Unfortunately I'm getting an error while I'm posting some bigger xmls, when the connection lasts longer than 10/15 min. (I assume It's some kind of timeout)

I corrected my SSL certs as it was mentioned in the link1 - configureClient() method is the same in my case as the solution from the one in the link1.

I added also System.setProperty("java.net.preferIPv4Stack" , "true"); - sometimes it solves Connection reset

Essential info:

Error: javax.ws.rs.ProcessingException: java.net.SocketException: Connection reset

Method: REST POST

Java version: 7

Engine: Jersey 2.x

Side: Client

System: Windows 7

My client:

   System.setProperty("java.net.preferIPv4Stack" , "true");

RestMethodes restMethodes = new RestMethodes();
ClientConfig config = new ClientConfig();
config = config.property(ClientProperties.CONNECT_TIMEOUT, 0);
config = config.property(ClientProperties.READ_TIMEOUT, 0);

config.property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true);

Client client = configureClient(config);
client.register(HttpAuthenticationFeature.basic(USER, PASS));

WebTarget target = client.target(SERVER_URL + "/bundles/assets");
Invocation.Builder responseInvocation = target.request(MediaType.APPLICATION_JSON);

// My exception is thrown there

Response response = responseInvocation.post(Entity.xml(assetsString)); 

String entity = response.readEntity(String.class);
//entity = jsonPrettyPrinter(entity);

if (entity.isEmpty() || entity.equals("")) {
    log.info("[POST ASSETS] Failed : Response is empty");
}
Response.StatusType codeName = response.getStatusInfo();
int code = response.getStatus();

if (code != 200) {
    log.error("[POST ASSETS] Failed : HTTP error code : " + response.getStatus() + "\n" + entity);
    response.close();
} else {
    log.info("[POST ASSETS] RESPONSE CODE ID : " + code + " CODE NAME : " + codeName);
    log.info("[POST ASSETS] RESPONSE : " + entity);
    response.close();
}
client.close();

My ERROR

Exception in thread "main" javax.ws.rs.ProcessingException: java.net.SocketException: Connection reset
at org.glassfish.jersey.client.internal.HttpUrlConnector.apply(HttpUrlConnector.java:287)
at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:252)
at org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.java:684)
at org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.java:681)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:228)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:444)
at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:681)
at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:437)
at org.glassfish.jersey.client.JerseyInvocation$Builder.post(JerseyInvocation.java:343)
at com.sas.spl.saslineagebridges.test.PostTester.main(PostTester.java:61)
Caused by: java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:209)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at sun.security.ssl.InputRecord.readFully(InputRecord.java:465)
at sun.security.ssl.InputRecord.read(InputRecord.java:503)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:973)
at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:930)
at sun.security.ssl.AppInputStream.read(AppInputStream.java:105)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:246)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:286)
at java.io.BufferedInputStream.read(BufferedInputStream.java:345)
at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:704)
at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:647)
at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:675)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1569)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1474)
at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:480)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:338)
at org.glassfish.jersey.client.internal.HttpUrlConnector._apply(HttpUrlConnector.java:399)
at org.glassfish.jersey.client.internal.HttpUrlConnector.apply(HttpUrlConnector.java:285)
... 11 more

EDIT:

I forgot to mention that I managed to post my request via CURL from bash with infinity timeout and keep alive, so It shouldn't be the servers issue. The CURL REST post took 24 min. and my java client throws connection reset after 15 min. In my opinion It might be my fault.

jjanczur
  • 117
  • 1
  • 9
  • See also https://stackoverflow.com/questions/585599/whats-causing-my-java-net-socketexception-connection-reset – Raedwald Jan 24 '19 at 12:43

1 Answers1

0

You are facing a timeout issue, although your client seems well configured. This timeout can be caused by any firewall, proxy, load-balancer, or even the server itself if it is running a web server like Apache in front of the application server. Please check what is in-between your client and the application server, and set timeouts accordingly everywhere.

It doesn't mean that you can't do nothing on the client itself, but it's much more difficult to solve there. On Windows you will need to enable the TCP keep-alives, first. After, according to the Client Transport you are using, we will try to add TCP keep-alives to the sockets built by the underlying factory, something similar that we know possible on Axis clients. This solution is more time-consuming for you.

Eugène Adell
  • 3,089
  • 2
  • 18
  • 34
  • 2
    Please state precisely how a connect or read timeout can cause a connection reset, and what TCP keepalive can do about fixing it. – user207421 Jan 31 '18 at 10:08
  • The connection reset is sent by an element between the client and the application server on which a timeout has occured. Closing a connection can be a FIN or an RST packet. The TCP keepalive sent by the client allows intermediaries such as firewalls to not fall in timeout. You already know this and it's in your book. A demonstration of the keepalive effect is here, and believe me it's working : http://blog.river-tiger.com/proxy-timeouts-tcp-keepalives – Eugène Adell Jan 31 '18 at 10:22
  • I enabled SSL tracing and got following message: main, handling exception: java.net.SocketException: Connection reset %% Invalidated: [Session-2, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256] main, SEND TLSv1.2 ALERT: fatal, description = unexpected_message main, WRITE: TLSv1.2 Alert, length = 26 main, Exception sending alert: java.net.SocketException: Connection reset by peer: socket write error main, called closeSocket() main, called close() main, called closeInternal(true) ######### And added keep-alive in header: .header("Connection", "keep-alive").post(Entity.xml(assetsString)); – jjanczur Jan 31 '18 at 14:52
  • The internet told me to force TLSv1 but I got similar exception: #############%% Invalidated: [Session-2, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA] main, SEND TLSv1 ALERT: fatal, description = unexpected_message main, WRITE: TLSv1 Alert, length = 32########## [link](https://github.com/OfficeDev/ews-java-api/issues/373) – jjanczur Jan 31 '18 at 15:23
  • Adding HTTP keep-alive is of no help, and this new trace doesn't give any new element unfortunately. I was talking about the TCP keep-alive. You see that my answer was down-voted, it's discouraging. As already said, check everything between the client and the server, adjust timeouts where necessary (for example if you have an Apache with ProxyPass : add the timeout key with a big value) – Eugène Adell Jan 31 '18 at 15:29