"Falló la construcción de la ruta PKIX" y "no se pudo encontrar una ruta de certificación válida para el objetivo solicitado"
Estoy tratando de obtener tweets usando la biblioteca twitter4j para mi proyecto java. En mi primera ejecución obtuve un error sobre el certificado sun.security.validator.ValidatorException
y sun.security.provider.certpath.SunCertPathBuilderException
. Luego añadí el certificado de twitter por:
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"
Pero sin éxito. Aquí está el procedimiento para obtener 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());
}
Y aquí está el 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
346
3
Después de muchas horas tratando de crear archivos de certificados para que mi instalación de Java 6 funcione con los nuevos certificados de Twitter, finalmente me topé con una solución increíblemente simple enterrada en un comentario en uno de los tableros de mensajes. Sólo tienes que copiar el archivo cacerts de una instalación de Java 7 y sobrescribir el de tu instalación de Java 6. Probablemente sea mejor hacer una copia de seguridad del archivo cacerts primero, pero luego sólo tienes que copiar el nuevo y ¡BOOM! simplemente funciona.
Tenga en cuenta que he copiado un archivo cacerts de Windows en una instalación de Linux y ha funcionado bien.
El archivo se encuentra en
jre/lib/security/cacerts
tanto en la antigua como en la nueva instalación de Java jdk.Espero que esto ahorre a alguien más horas de agravamiento.
Me he encontrado con este problema que me ha llevado muchas horas de investigación para solucionarlo, especialmente con los certificados autogenerados, que a diferencia de los oficiales, son bastante complicados y a Java no le gustan mucho.
Por favor, revisa el siguiente enlace: Resolver el problema de los certificados en Java
Básicamente hay que añadir el certificado del servidor a los certificados de Java Home.
InstallCert
y ejecútelo mientras el servidor se está ejecutando, proporcionando los siguientes argumentosserver[:port]
. No se necesita ninguna contraseña, ya que la contraseña original funciona para los certificados Java ("changeit").jssecerts
dentro del directorio donde ejecutó el Programa (Si se ejecuta desde Eclipse entonces asegúrese de configurar el directorio de trabajo enRun -> Configuraciones
).$JAVA_HOME/jre/lib/security
.Después de seguir estos pasos, las conexiones con el certificado ya no generarán excepciones dentro de Java.
El siguiente código fuente es importante y desapareció de los blogs de (Sun) Oracle, la única página que encontré fue en el enlace proporcionado, por lo que lo adjunto en la respuesta para cualquier referencia.
Aquí normalmente este tipo de excepción ocurre cuando hay un desajuste en la RUTA del certificado de confianza. Compruebe la configuración o la ruta donde se requiere este certificado de servidor para la comunicación segura.