ClassNotFoundException on org.apache.http.ssl.TrustStrategy

24,857

Solution 1

if you are using a maven project, add the below dependency in your pom.xml file.

 <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
        <version>4.5.3</version>
</dependency>

Solution 2

So, I replaced the sslcontext methods from apache httpclient and httpcore with javax sslcontext methods. Now, everything works fine. Remembering, that the above code was working normally on pure java. The real problem was when running on Minecraft server.

Anyway, i will put below the new code, for documentation, maybe helps someone.

package com.b5team.postrequest;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

public class HttpsPOSTRequest {

    public static void sendRequest(String myurl, String hash, String args[]) throws NoSuchAlgorithmException, KeyManagementException {

        try {
            SSLContext context = SSLContext.getInstance("TLS");
            context.init(new KeyManager[0], new TrustManager[] {new DefaultTrustManager()}, new SecureRandom());
            SSLContext.setDefault(context);

            URL url = new URL(myurl);
            HttpsURLConnection con = (HttpsURLConnection)url.openConnection();
            con.setHostnameVerifier(new HostnameVerifier() {
                @Override
                public boolean verify(String arg0, SSLSession arg1) {
                    return true;
                }
            });

            con.setRequestMethod("POST");
            con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            con.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0;Windows98;DigExt)");
            con.setDoOutput(true);
            con.setDoInput(true);

            ArrayList<String> params = new ArrayList<String>(args.length + 1);

            DataOutputStream output = new DataOutputStream(con.getOutputStream());
            output.writeBytes("hash=" + hash);
            for(int i = 0; i < params.size(); i++) {
                output.writeBytes("&");
                output.writeBytes("arg" + i + "=" + args[i]);
                output.flush();
            }

            output.flush();
            output.close();

            DataInputStream input = new DataInputStream(con.getInputStream());
            BufferedReader reader = new BufferedReader(new InputStreamReader(input));
            String line;

            System.out.println("[POSTRequest] Data sent successfully!");
            System.out.println("[POSTRequest] Resp Code:"+con.getResponseCode());
            System.out.println("[POSTRequest] Resp Message:"+con.getResponseMessage());

            while ((line = reader.readLine()) != null) {
                System.out.println("[POSTRequest] Report: "+line);
            }

            input.close();

        } catch (UnsupportedEncodingException e) {
            System.out.println("[POSTRequest] Encoding error. Maybe string have invalid caracters.");
            e.printStackTrace();
        } catch (MalformedURLException e) {
            System.out.println("[POSTRequest] Invalid URL. Verify your URL and try again.");
            e.printStackTrace();
        } catch (IOException e) {
            System.out.println("[POSTRequest] Error on HTTPS connection.");
            e.printStackTrace();
        }
    }

    private static class DefaultTrustManager implements X509TrustManager {

        @Override
        public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}

        @Override
        public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }
    }
}
Share:
24,857
bbruno5
Author by

bbruno5

Updated on June 26, 2020

Comments

  • bbruno5
    bbruno5 almost 4 years

    I'm trying to run a plugin that makes HTTP/HTTPS POST requests. On it its declared the needed dependencies, that is httpclient and httpcore. I'm using versions 4.5.3 and 4.4.6 respectively. Although imported correctly all (I mean), I got this error on execution time:

    Caused by: java.lang.NoClassDefFoundError: 
    org/apache/http/ssl/TrustStrategy
    25.06 19:59:12 [Server] INFO at 
    com.b5team.postrequest.Main.onCommand(Main.java:77) ~[?:?]
    25.06 19:59:12 [Server] INFO at 
    org.bukkit.command.PluginCommand.execute(PluginCommand.java:44) ~
    [Spigot.jar:git-Spigot-3fb9445-6e3cec8]
    25.06 19:59:12 [Server] INFO ... 10 more
    25.06 19:59:12 [Server] INFO Caused by: 
    java.lang.ClassNotFoundException: org.apache.http.ssl.TrustStrategy
    

    And here is my code:

    package com.b5team.postrequest;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.security.KeyManagementException;
    import java.security.KeyStoreException;
    import java.security.NoSuchAlgorithmException;
    import java.security.cert.CertificateException;
    import java.security.cert.X509Certificate;
    import java.util.ArrayList;
    import java.util.List;
    
    import javax.net.ssl.HostnameVerifier;
    import javax.net.ssl.SSLContext;
    
    import org.apache.http.HttpEntity;
    import org.apache.http.HttpResponse;
    import org.apache.http.NameValuePair;
    import org.apache.http.client.ClientProtocolException;
    import org.apache.http.client.HttpClient;
    import org.apache.http.client.entity.UrlEncodedFormEntity;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.config.Registry;
    import org.apache.http.config.RegistryBuilder;
    import org.apache.http.conn.socket.ConnectionSocketFactory;
    import org.apache.http.conn.socket.PlainConnectionSocketFactory;
    import org.apache.http.conn.ssl.NoopHostnameVerifier;
    import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
    import org.apache.http.ssl.SSLContextBuilder;
    import org.apache.http.conn.ssl.TrustStrategy;
    import org.apache.http.impl.client.HttpClientBuilder;
    import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
    import org.apache.http.message.BasicNameValuePair;
    
    public class SocketPOSTRequest {
    
        public void sendRequest(String myurl, String hash, String args[]) throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException, ClientProtocolException, IOException {
    
            HttpClientBuilder b = HttpClientBuilder.create();
    
            SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
    
                public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
                    return true;
                }
            }).build();
    
            b.setSSLContext(sslContext);
    
            HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE;
    
            SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
            Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory> create()
                    .register("http", PlainConnectionSocketFactory.getSocketFactory())
                    .register("https", sslSocketFactory)
                    .build();
    
            PoolingHttpClientConnectionManager connMgr = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
            b.setConnectionManager(connMgr);
    
            HttpClient client = b.build();
            HttpPost post = new HttpPost(myurl);
    
            List<NameValuePair> params = new ArrayList<NameValuePair>(args.length);
            params.add(new BasicNameValuePair("hash", hash));
    
            for(int i = 0; i < args.length; i++) {
                params.add(new BasicNameValuePair("arg"+i, args[i]));
            }
    
            post.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
            HttpResponse response = client.execute(post);
            HttpEntity entity = response.getEntity();
    
            if (entity != null) {
    
                InputStream in = entity.getContent();
                BufferedReader reader = new BufferedReader(new InputStreamReader(in));
                String line;
    
                System.out.println("[POSTRequest] Data sent successfully!");
    
                while ((line = reader.readLine()) != null) {
                    System.out.println("[POSTRequest] Report: "+line);
                }
            }
        }
    }
    

    EDIT: I'm using Ant to build, and the dependencies are correctly added. I tested too with Maven, adding the dependencies, but the error remains.

    EDIT2: Switched to Maven, added maven-shade-plugin and maven-compile-plugin. The error disappeared, but now got this java.lang.NoSuchMethodError: org.apache.http.impl.client.HttpClientBuilder.setSSLContext. When running with junit, don't occurs any errors. It only occurs when running on server, that is Spigot 1.11.2 Minecraft Server.

  • bbruno5
    bbruno5 almost 7 years
    So, I'm using Ant, but when trying with Maven, the error remains.
  • Ali Akbarpour
    Ali Akbarpour almost 7 years
    which version of httpclient you are using?
  • bbruno5
    bbruno5 almost 7 years
    httpclient 4.5.3 and httpcore 4.4.6
  • Ali Akbarpour
    Ali Akbarpour almost 7 years
    please can you test with httpclient 4.5.2 and httpcore 4.4
  • bbruno5
    bbruno5 almost 7 years
    Ok, just a moment
  • bbruno5
    bbruno5 almost 7 years
    Error persists.
  • Asantoya17
    Asantoya17 about 6 years
    is there any other workarround to solve this issue? im using maven with, httpclient 4.5.3 and httpcore 4.4.6 + java 8
  • bbruno5
    bbruno5 about 6 years
    All depends from the correct configs of maven file. After a bit time I got apache httpclient working thanks to shader method on maven.
  • febot
    febot over 3 years
    I guess you mean JAR shading? I think your issue was rather a wrong settings of dependencies. Maybe you ended up with a wrong setup which works by accident. E.g. it worked in JUnit because the test dependencies included the lib, but it was not included on Minecraft server's classpath. The way to troubleshoot this is to 1) Check the full dependency tree, including scopes. 2) Figure out the .jar's that have all the runtime dependencies. 3) Add these jars to the server's classpath. 3b) Optionally you may created a shaded jar to distribute your plugin as one archive, but that can bring issues.