How to resolve TLS version issue due to Salesforce disabling TLS 1.0 : REST API

I have been using Apache HttpClient to consume Salesforce REST API services. With change made by Salesforce disabling TLS 1.0 had some negative impact on the code which I have been using. As per my previous article if you are not using java 8, you'll face these issues since TLS 1.0 is disabled by default in Java 8

You are likely to get "UNSUPPORTED_CLIENT TLS 1.0 has been disabled in the organization. Please use TLS 1.1 or higher" error if you do not update your REST client.

There are few solutions for this issue.
eg: System.setProperty("https.protocols", "TLSv1.1,TLSv1.2");
      Update eclipse ,ini file by including -Dhttps.protocols=TLSv1.1,TLSv1.2 

The following method is somewhat a better fix to the problem than the above generic solutions which might not work on some instances.In this code I'm updating a resource in the Salesforce via a PATCH request. I have defined a External Id for this resource, so I'm using the external id to update the record.

  • Create CustomHttpsSocketFactory and ensure that is only supports TLSv1.2
 class CustomHttpsSocketFactory implements SecureProtocolSocketFactory {  
   private final SecureProtocolSocketFactory base;  
   public CustomHttpsSocketFactory(ProtocolSocketFactory base) {  
    if (base == null || !(base instanceof SecureProtocolSocketFactory))  
      throw new IllegalArgumentException();  
    this.base = (SecureProtocolSocketFactory)base;  
   }  
   private Socket acceptOnlyTLS(Socket socket) {  
    if (!(socket instanceof SSLSocket))  
      return socket;  
    SSLSocket sslSocket = (SSLSocket)socket;  
    sslSocket.setEnabledProtocols(new String[]{"TLSv1.2"});  
    return sslSocket;  
   }  
   @Override public Socket createSocket(String host, int port) throws IOException {  
    return acceptOnlyTLS(base.createSocket(host, port));  
   }  
   @Override public Socket createSocket(String host, int port, InetAddress localAddress, int localPort) throws IOException {  
    return acceptOnlyTLS(base.createSocket(host, port, localAddress, localPort));  
   }  
   @Override public Socket createSocket(String host, int port, InetAddress localAddress, int localPort, HttpConnectionParams params) throws IOException {  
    return acceptOnlyTLS(base.createSocket(host, port, localAddress, localPort, params));  
   }  
   @Override public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException {  
    return acceptOnlyTLS(base.createSocket(socket, host, port, autoClose));  
   }  


  • Register the Protocol before executing Web Service request. Here the external id field is Partner_Community_ID__c. To create a PATCH request we'll be using the PostMethod and will override the getName() method.(Refer the sample code).

  public static String updateSubCommunity(JSONObject partnerCommunity, JSONObject headerData) throws JSONException {  
    String requestBody = "{\"OrgID__c\":\"" + partnerCommunity.getString("OrgID__c") + "\"," + "\"Partner_Community_Description__c\":\"" + partnerCommunity.getString("Partner_Community_Description__c") + "\"" + "," + "\"Partner_Community_Name__c\":\"" + partnerCommunity.getString("Partner_Community_Name__c") + "\"," + "\"Partner_Community_Status__c\":\"" + partnerCommunity.getString("Partner_Community_Status__c") + "\"}";  
    String requestUrl = headerData.getString("instance_url") + SUBCOMMUNITY_SERVICE_URL + "/Partner_Community_ID__c/" + partnerCommunity.getString("Partner_Community_ID__c");  
    StringBuffer responseBuffer = null;  
    //requestUrl="https://.salesforce.com/services/data/v38.0/sobjects///"; 
    try {  
      String scheme = "https";  
      Protocol baseHttps = Protocol.getProtocol(scheme);  
      int defaultPort = baseHttps.getDefaultPort();  
      ProtocolSocketFactory baseFactory = baseHttps.getSocketFactory();  
      ProtocolSocketFactory customFactory = new CustomHttpsSocketFactory(baseFactory);  
      Protocol customHttps = new Protocol(scheme, customFactory, defaultPort);  
      Protocol.registerProtocol(scheme, customHttps);  
      PostMethod postMethod = new PostMethod(requestUrl) {  
       @Override public String getName() {  
         return "PATCH";  
       }  
      };  
      postMethod.setRequestHeader("Authorization", "Bearer " + headerData.getString("access_token"));  
      postMethod.setRequestEntity(new StringRequestEntity(requestBody, "application/json", "UTF-8"));  
      HttpClient c = new HttpClient();  
      int statusCode = c.executeMethod(postMethod);  
      responseBuffer = new StringBuffer();  
      responseBuffer.append(statusCode);
      if (statusCode > 299)  
       try (BufferedReader rdr = new BufferedReader(new InputStreamReader(postMethod.getResponseBodyAsStream()))) {  
         for (int c1; (c1 = rdr.read()) != -1;) {  
          responseBuffer.append((char)c1);  
         }  
       }  
    }  
    catch (Exception e) {  
      throw new RuntimeException(e.getMessage());  
    }  
    return responseBuffer.toString();  
   }  
 }  

Comments