3

Below are my configurations

java version "1.8.0_101" Java(TM) SE Runtime Environment (build 1.8.0_101-b13) Java HotSpot(TM) 64-Bit Server VM (build 25.101-b13, mixed mode)

Using Apache httpclient v4.4 to call the Restful service, The service URL has a valid certificate (SHA2)

Using apache httpclient we are calling the service. Below is the code

private static CloseableHttpClient appHttpClient() throws Exception {
    if (null != httpclient) {
        return httpclient;
    }
    final Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder
            .<ConnectionSocketFactory> create().register("http", PlainConnectionSocketFactory.INSTANCE)
            .register("https", new SSLConnectionSocketFactory(trustAllSSLContext())).build();

    final PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
    cm.setMaxTotal(HTTP_MAX_CON);
    cm.setDefaultMaxPerRoute(HTTP_CON_ROUTE);

    final RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(HTTP_CON_TO)
            .setConnectionRequestTimeout(HTTP_REQ_CON_TO).setSocketTimeout(HTTP_SO_TO).build();

    // final SSLConnectionSocketFactory factory = new
    // SSLConnectionSocketFactory(getSSLContext());

    httpclient = HttpClients.custom().setConnectionManager(cm).setDefaultRequestConfig(requestConfig).build();

    return httpclient;
}

public static SSLContext trustAllSSLContext() throws Exception {
    if (sslContext != null) {
        return sslContext;
    }
    sslContext = SSLContext.getInstance("TLSv1.2");
    sslContext.init(null, null, null);
    System.out.println(
            "SSLContext :: Protocol :: " + sslContext.getProtocol() + " Provider :: " + sslContext.getProvider());
    return sslContext;
}

The service call is failing intermittently, there is batch process which calls our services in a loop, say 30 calls to services so some of them are failing and some of them are successful, for failed calls we are getting below exception.

java.lang.IllegalStateException: SSLContextImpl is not initialized
   at sun.security.ssl.SSLContextImpl.engineGetSocketFactory(SSLContextImpl.java:181)
   at javax.net.ssl.SSLContext.getSocketFactory(SSLContext.java:294)
   at org.apache.http.conn.ssl.SSLConnectionSocketFactory.<init>(SSLConnectionSocketFactory.java:262)
   at org.apache.http.conn.ssl.SSLConnectionSocketFactory.<init>(SSLConnectionSocketFactory.java:205)
   at com.wdpr.payment.helper.HttpHelper.appHttpClient(HttpHelper.java:63)
   at com.wdpr.payment.helper.HttpHelper.makePostCall(HttpHelper.java:142)...

Any one has any idea why it is failing for this exception intermittently.

Shantanoo K
  • 765
  • 5
  • 15
  • 43

2 Answers2

1

In the code snippets I found online,

sslContext = SSLContext.getInstance("");

was called with "SSL" instead of "TLSv1.2".

To force ssl sockets to use TLSv1.2, I used How to force Commons HTTPClient 3.1 to use TLS 1.2 only for HTTPS?

(edit)

On a possibly related note, when using Http Commons MultiThreadedHttpConnectionManager, we have to call

manager.closeIdleConnections(10000); 
manager.deleteClosedConnections();

after each http call, otherwise we experiment some connection failures every N calls.

Community
  • 1
  • 1
louisgab
  • 2,414
  • 1
  • 15
  • 9
1

If 'The service URL has a valid certificate' is true - just remove all SSL-related customizations.

This one ( trust them all approach ):

new SSLConnectionSocketFactory(trustAllSSLContext())

is actually a hack for non-valid certificates, as quick fix - try to add 'synchronized' to trustAllSSLContext method.

JuanMoreno
  • 2,498
  • 1
  • 25
  • 34
Alex Chernyshev
  • 1,719
  • 9
  • 11