title: How can I retry using DefaultHttpRequestRetryHandler(HTTPClient) when SocketException occurs during SSL communication on java 11?
body: <p>How should I implement it to be able to retry SSL communication using <a href="http://hc.apache.org/httpcomponents-client-ga/" rel="nofollow noreferrer">httpclient</a> on  java11?</p>
  
  <p>Is it better to override DefaultHttpRequestRetryHandler as shown below?<br> Is there a more better way?</p>
  
  <pre class="lang-java prettyprint-override"><code>  public class HttpRequestRetryHandler extends DefaultHttpRequestRetryHandler {
  
      @Override
      public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
        IOException cause = exception;
        if (exception instanceof SSLException) {
          if (exception.getCause() != null &amp;&amp; exception.getCause() instanceof IOException) {
            cause = (IOException) exception.getCause();
          }
        }
        return super.retryRequest(cause, executionCount, context);
      }
    }
  </code></pre>
  
  <p>In Java 11, SocketException is not retried , because SocketException is wrapped with SSLException.</p>
  
  <p>I read the following content.</p>
  
  <ul>
  <li><a href="https://bugs.openjdk.java.net/browse/JDK-8214339" rel="nofollow noreferrer">https://bugs.openjdk.java.net/browse/JDK-8214339</a></li>
  <li><p><a href="http://hg.openjdk.java.net/jdk-updates/jdk11u/rev/18b4acfaaa97" rel="nofollow noreferrer">http://hg.openjdk.java.net/jdk-updates/jdk11u/rev/18b4acfaaa97</a></p>
  
  <pre><code>if ((cause != null) &amp;&amp; (cause instanceof IOException)) {
      ssle = new SSLException(reason);
  } 
  </code></pre></li>
  <li><p><a href="https://hc.apache.org/httpcomponents-client-ga/tutorial/html/fundamentals.html" rel="nofollow noreferrer">https://hc.apache.org/httpcomponents-client-ga/tutorial/html/fundamentals.html</a> <br>
  DefaultHttpRequestRetryHandler does not retry when an SSLException occurs.</p></li>
  </ul>
  
  <p>When using java11, the following error occurs randomly with a probability of less than 0.01%.</p>
  
  <pre class="lang-java prettyprint-override"><code>javax.net.ssl.SSLException: Connection reset
      at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:127)
      at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:321)
      at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:264)
      at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:259)
      at java.base/sun.security.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1314)
      at java.base/sun.security.ssl.SSLSocketImpl$AppInputStream.read(SSLSocketImpl.java:839)
      at org.apache.http.impl.io.SessionInputBufferImpl.streamRead(SessionInputBufferImpl.java:137)
      at org.apache.http.impl.io.SessionInputBufferImpl.fillBuffer(SessionInputBufferImpl.java:153)
      at org.apache.http.impl.io.SessionInputBufferImpl.readLine(SessionInputBufferImpl.java:280)
      at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:138)
      at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:56)
      at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:259)
      at org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:163)
      at org.apache.http.impl.conn.CPoolProxy.receiveResponseHeader(CPoolProxy.java:157)
      at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:273)
      at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:125)
      at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:272)
      at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:186)
      at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
      at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
      at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
      at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
      at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:56)
      at org.springframework.http.client.HttpComponentsClientHttpRequest.executeInternal(HttpComponentsClientHttpRequest.java:87)
      at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48)
      at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:53)
      at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:735)
      ... 81 common frames omitted
      Suppressed: java.net.SocketException: Broken pipe (Write failed)
          at java.base/java.net.SocketOutputStream.socketWrite0(Native Method)
          at java.base/java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:110)
          at java.base/java.net.SocketOutputStream.write(SocketOutputStream.java:150)
          at java.base/sun.security.ssl.SSLSocketOutputRecord.encodeAlert(SSLSocketOutputRecord.java:81)
          at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:352)
          ... 106 common frames omitted
  Caused by: java.net.SocketException: Connection reset
      at java.base/java.net.SocketInputStream.read(SocketInputStream.java:186)
      at java.base/java.net.SocketInputStream.read(SocketInputStream.java:140)
      at java.base/sun.security.ssl.SSLSocketInputRecord.read(SSLSocketInputRecord.java:448)
      at java.base/sun.security.ssl.SSLSocketInputRecord.bytesInCompletePacket(SSLSocketInputRecord.java:68)
      at java.base/sun.security.ssl.SSLSocketImpl.readApplicationRecord(SSLSocketImpl.java:1104)
      at java.base/sun.security.ssl.SSLSocketImpl$AppInputStream.read(SSLSocketImpl.java:823)
      ... 102 common frames omitted
  </code></pre>