I'm trying to get tweets using twitter4j library for my java project. On my first run I got an error about certificate sun.security.validator.ValidatorException
and sun.security.provider.certpath.SunCertPathBuilderException
. Then I added twitter certificate by:
C:\Program Files\Java\jdk1.7.0_45\jre\lib\security>keytool -importcert -trustcacerts -file PathToCert -alias ca_alias -keystore "C:\Program Files\Java\jdk1.7.0_45\jre\lib\security\cacerts"
But without success. Here is the procedure to get twitters:
public static void main(String[] args) throws TwitterException {
ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setDebugEnabled(true)
.setOAuthConsumerKey("myConsumerKey")
.setOAuthConsumerSecret("myConsumerSecret")
.setOAuthAccessToken("myAccessToken")
.setOAuthAccessTokenSecret("myAccessTokenSecret");
TwitterFactory tf = new TwitterFactory(cb.build());
Twitter twitter = tf.getInstance();
try {
Query query = new Query("iphone");
QueryResult result;
result = twitter.search(query);
System.out.println("Total amount of tweets: " + result.getTweets().size());
List<Status> tweets = result.getTweets();
for (Status tweet : tweets) {
System.out.println("@" + tweet.getUser().getScreenName() + " : " + tweet.getText());
}
} catch (TwitterException te) {
te.printStackTrace();
System.out.println("Failed to search tweets: " + te.getMessage());
}
And here is the error:
sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
Relevant discussions can be found on the Internet at:
http://www.google.co.jp/search?q=d35baff5 or
http://www.google.co.jp/search?q=1446302e
TwitterException{exceptionCode=[d35baff5-1446302e 43208640-747fd158 43208640-747fd158 43208640-747fd158], statusCode=-1, message=null, code=-1, retryAfter=-1, rateLimitStatus=null, version=3.0.5}
at twitter4j.internal.http.HttpClientImpl.request(HttpClientImpl.java:177)
at twitter4j.internal.http.HttpClientWrapper.request(HttpClientWrapper.java:61)
at twitter4j.internal.http.HttpClientWrapper.get(HttpClientWrapper.java:81)
at twitter4j.TwitterImpl.get(TwitterImpl.java:1929)
at twitter4j.TwitterImpl.search(TwitterImpl.java:306)
at jku.cc.servlets.TweetsAnalyzer.main(TweetsAnalyzer.java:38)
Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.ssl.Alerts.getSSLException(Unknown Source)
at sun.security.ssl.SSLSocketImpl.fatal(Unknown Source)
at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
at sun.security.ssl.ClientHandshaker.serverCertificate(Unknown Source)
at sun.security.ssl.ClientHandshaker.processMessage(Unknown Source)
at sun.security.ssl.Handshaker.processLoop(Unknown Source)
at sun.security.ssl.Handshaker.process_record(Unknown Source)
at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
at java.net.HttpURLConnection.getResponseCode(Unknown Source)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(Unknown Source)
at twitter4j.internal.http.HttpResponseImpl.<init>(HttpResponseImpl.java:34)
at twitter4j.internal.http.HttpClientImpl.request(HttpClientImpl.java:141)
... 5 more
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.validator.PKIXValidator.doBuild(Unknown Source)
at sun.security.validator.PKIXValidator.engineValidate(Unknown Source)
at sun.security.validator.Validator.validate(Unknown Source)
at sun.security.ssl.X509TrustManagerImpl.validate(Unknown Source)
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(Unknown Source)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
... 20 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(Unknown Source)
at java.security.cert.CertPathBuilder.build(Unknown Source)
... 26 more
Failed to search tweets: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
I wanted to import certificate for smtp.gmail.com
Only solution worked for me is 1. Enter command to view this certificate
Copy and save the lines between "-----BEGIN CERTIFICATE-----" and "-----END CERTIFICATE-----" into a file, gmail.cer
Run
Enter password chageit
Click yes to import the certificate
Restart java
now run the command and you are good to go
The reason, we get above error is that JDK is bundled with a lot of trusted Certificate Authority(CA) certificates into a file called ‘cacerts’ but this file has no clue of our self-signed certificate. In other words, the cacerts file doesn’t have our self-signed certificate imported and thus doesn’t treat it as a trusted entity and hence it gives the above error.
How to fix the above error
To fix the above error, all we need is to import the self-signed certificate into the cacerts file.
First, locate the cacerts file. We will need to find out the JDK location. If you are running your application through one of the IDE’s like Eclipse or IntelliJ Idea go to project settings and figure out what is the JDK location. For e.g on a Mac OS typical location of cacerts file would be at this location /Library/Java/JavaVirtualMachines/ {{JDK_version}}/Contents/Home/jre/lib/security on a Window’s machine it would be under {{Installation_directory}}/{{JDK_version}}/jre/lib/security
Once you have located the cacerts file, now we need to import our self-signed certificate to this cacerts file. Check the last article, if you don’t know how to generate the self-signed certificate correctly.
If you don’t have a certificate file(.crt) and just have a .jks file you can generate a .crt file by using below command. In case you already have a .crt/.pem file then you can ignore below command
##To generate certificate from keystore(.jks file) ####
Above step will generate a file called selfsigned.crt.Now Import the certificate to cacerts
Now add the certificate to JRE/lib/security/cacerts (trustore) Now add the certificate to JRE/lib/security/cacerts (trustore)for e.g
That’s all, restart your application and it should work fine. If it still doesn’t work and get an SSL handshake exception. It probably means you are using different domain then registered in the certificate.
The Link with detailed explanation and step by step resolution is over here.
I have stumbled upon this issue which took many hours of research to fix, specially with auto-generated certificates, which unlike Official ones, are quite tricky and Java does not like them that much.
Please check the following link: Solve Problem with certificates in Java
Basically you have to add the certificate from the server to the Java Home certs.
InstallCert
and execute it while the server is running, providing the following argumentsserver[:port]
. No password is needed, as the original password works for the Java certs ("changeit").jssecerts
file inside the directory where you executed the Program (If executed from Eclipse then make sure you configure the Work directory inRun -> Configurations
).$JAVA_HOME/jre/lib/security
After following these steps, the connections with the certificate will not generate exceptions anymore within Java.
The following source code is important and it disappeared from (Sun) Oracle blogs, the only page I found it was on the link provided, therefore I am attaching it in the answer for any reference.
I was facing the same issue and get it resolved using the below simple steps:
1) Download the InstallCert.java from google
2) Compile it using javac InstallCert.java
3) Run InstallCert.java using java InstallCert.java, with the hostname and https port, and press “1” when asking for input. It will add the “localhost” as a trusted keystore, and generate a file named “jssecacerts“ as below:
java InstallCert localhost:443
4) copy the jssecacerts into $JAVA_HOME/jre/lib/security folder
Main source to resolve the issue here is:
https://ankurjain26.blogspot.in/2017/11/javaxnetsslsslhandshakeexception.html