I'm using HttpClient 3.1 to talk to a remote server through a proxy via HTTPS and client certificate authentication. This has been working just fine for a couple of weeks now, until I started experiencing SSLHandshakeExceptions recently.
I assume the root cause lies with the remote server (since I haven't changed a damn thing), but I noticed my error handling may need some work.
When anything goes wrong during communication, I retry my request a few times, then give up. I am still able to sucessfully communicate with the remote server after a SSLHandshakeException has occured, but at some point, all requests fail with SSLHandshakeExceptions. Restarting the app fixes this, so it seems there's a problem in my app, in addition to the root cause on the remote server.
A possible explanation would be that the SSL connections always throw SSLHandshakeExceptions after the first one occurs, and that HttpClient somehow re-uses them.
Does that sound reasonable? How do I troubleshoot this, given that I cannot reproduce the problem on demand?
Clarification: My main goal is to improve my app's robustness and error handling, since I firmly believe the root cause lies with the remote server and is therefore beyond my control.
Stacktrace:
org.springframework.ws.client.WebServiceIOException: I/O error:
Remote host closed connection during handshake; nested exception is
javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:507)
at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:350)
at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:344)
at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:336)
...
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:98)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:207)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:885)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
at java.lang.Thread.run(Thread.java:619)
Caused by: javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:808)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1096)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:623)
at com.sun.net.ssl.internal.ssl.AppOutputStream.write(AppOutputStream.java:59)
at java.io.BufferedOutputStream.write(BufferedOutputStream.java:105)
at org.apache.commons.httpclient.HttpConnection.write(HttpConnection.java:974)
at org.apache.commons.httpclient.HttpConnection.write(HttpConnection.java:942)
at org.apache.commons.httpclient.HttpConnection.print(HttpConnection.java:1032)
at org.apache.commons.httpclient.HttpMethodBase.writeRequestLine(HttpMethodBase.java:2077)
at org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.java:1918)
at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:993)
at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:397)
at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:170)
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:396)
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:324)
...
at org.springframework.ws.client.core.WebServiceTemplate.sendRequest(WebServiceTemplate.java:585)
at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:548)
at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:501)
... 16 more
Caused by: java.io.EOFException: SSL peer shut down incorrectly
at com.sun.net.ssl.internal.ssl.InputRecord.read(InputRecord.java:333)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:789)
... 34 more