ClassNotFoundException on org.apache.http.ssl.TrustStrategy
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;
}
}
}
bbruno5
Updated on June 26, 2020Comments
-
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
andhttpcore
. 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 almost 7 yearsSo, I'm using Ant, but when trying with Maven, the error remains.
-
Ali Akbarpour almost 7 yearswhich version of httpclient you are using?
-
bbruno5 almost 7 yearshttpclient 4.5.3 and httpcore 4.4.6
-
Ali Akbarpour almost 7 yearsplease can you test with httpclient 4.5.2 and httpcore 4.4
-
bbruno5 almost 7 yearsOk, just a moment
-
bbruno5 almost 7 yearsError persists.
-
Asantoya17 about 6 yearsis there any other workarround to solve this issue? im using maven with, httpclient 4.5.3 and httpcore 4.4.6 + java 8
-
bbruno5 about 6 yearsAll depends from the correct configs of maven file. After a bit time I got apache httpclient working thanks to shader method on maven.
-
febot over 3 yearsI 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.