2013-02-20 52 views
1

我试图从使用Twitter4J的Twitter流式API检索推文。该项目使用SSLSocket连接到远程服务器以检索一些数据,然后调用Twitter4J。问题是,如果我建立这方面的Twitter4J出现此异常:使用后连接到Twitter SSLSocketFactory

[星期三2月20日11时32分02秒CET 2013] sun.security.validator.ValidatorException:PKIX路径建设 失败:阳光下。 security.provider.certpath.SunCertPathBuilderException: 无法找到请求的目标的有效证书路径

如果我不进行连接,我清理下一个线之间密钥库不会出现这种情况:

System.clearProperty("javax.net.ssl.trustStore"); 
System.clearProperty("javax.net.ssl.trustStorePassword"); 

代码连接是这个:

private String publishFetcher() throws UnknownHostException, IOException { 
    // Set trustStore. 
    System.setProperty("javax.net.ssl.trustStore", properties.getProperty("trustedStore")); 
    System.setProperty("javax.net.ssl.trustStorePassword", properties.getProperty("trustedStorePassword")); 

    String host = properties.getProperty("host"); 
    int hostPort = Integer.parseInt(properties.getProperty("host_port")); 
    SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault(); 
    SSLSocket socket = (SSLSocket) factory.createSocket(host, hostPort); 

    // Get input and output streams from socket connection. 
    BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
    PrintWriter output = new PrintWriter(socket.getOutputStream()); 

    // Request connection token to controller 
    String connectionToken = getConnectionToken(input, output); 

    // Publish fetcher 
    final int rmiPort = Integer.parseInt(properties.getProperty("rmi_port")); 
    TwitterFetcher fetcher = new TwitterFetcher(connector); 
    Fetcher stub = (Fetcher) UnicastRemoteObject.exportObject(fetcher, 0); 
    Registry registry = LocateRegistry.createRegistry(rmiPort); 
    registry.rebind(connectionToken, stub); 

    // Send RMI port 
    output.write(String.valueOf(rmiPort) + "\n"); 
    output.flush(); 

    input.close(); 
    output.close(); 

    // Clean trusteStore properties. 
    System.clearProperty("javax.net.ssl.trustStore"); 
    System.clearProperty("javax.net.ssl.trustStorePassword"); 

    return connectionToken; 
} 

我认为,因为我在不同项目测试出头的问题与相关的SSLSocketFactory。例如,此代码的工作就像一个魅力:

SSLSocketFactory deffactory = (SSLSocketFactory) SSLSocketFactory.getDefault(); 
System.setProperty("javax.net.ssl.trustStore", "sttv_keystore"); 
System.setProperty("javax.net.ssl.trustStorePassword", "Smart.Table"); 

SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault(); 

factory = deffactory; 
// Twitter4J code... 

但这码不起作用:

System.setProperty("javax.net.ssl.trustStore", "sttv_keystore"); 
System.setProperty("javax.net.ssl.trustStorePassword", "Smart.Table"); 

SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault(); 
// Twitter4J code... 

我不能这样做,我真正的项目,因为休息......几乎一切^^

可能是什么问题?和解决方案?

+0

另请参阅[如何解决SSLHandshakeException?为什么我得到它?](https://stackoverflow.com/questions/23139327/how-to-resolve-sslhandshakeexception-why-am-i-getting-it)。这似乎相关,因为我相信这两个问题都基于Twitter4J。 – jww 2014-04-27 00:48:02

回答

1

代码的问题是我正在替换信任存储而不是为我的应用程序创建一个新的信任存储。解决问题的代码是下一个:

private SSLSocket getSSLSocket() throws TrackerSSLConnectionException { 
    try { 
     // Load properties. 
     String keystore = properties.getProperty("keystore"); 
     String passphrase = properties.getProperty("keystorePassphrase"); 
     String host = properties.getProperty("host"); 
     int hostPort = Integer.parseInt(properties.getProperty("host_port")); 

     // Create keystore. 
     KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); 
     keyStore.load(new FileInputStream(keystore), passphrase.toCharArray()); 

     // Get factory for the given keystore. 
     TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
     tmf.init(keyStore); 
     SSLContext ctx = SSLContext.getInstance("SSL"); 
     ctx.init(null, tmf.getTrustManagers(), null); 
     SSLSocketFactory factory = ctx.getSocketFactory(); 

     return (SSLSocket) factory.createSocket(host, hostPort); 
    } catch (Exception e) { 
     throw new TrackerSSLConnectionException(e.getMessage(), e.getCause()); 
    } 
} 

private String publishFetcher() throws TrackerSSLConnectionException, IOException { 
    // Get socket connection. 
    SSLSocket socket = getSSLSocket(); 

    // Get input and output streams from socket. 
    BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
    PrintWriter output = new PrintWriter(socket.getOutputStream()); 

    // Request connection token to controller. 
    String connectionToken = getConnectionToken(input, output); 

    // Publish fetcher. 
    final int rmiPort = Integer.parseInt(properties.getProperty("rmi_port")); 
    TwitterFetcher fetcher = new TwitterFetcher(connector); 
    Fetcher stub = (Fetcher) UnicastRemoteObject.exportObject(fetcher, 0); 
    Registry registry = LocateRegistry.createRegistry(rmiPort); 
    registry.rebind(connectionToken, stub); 

    // Send RMI port. 
    output.write(String.valueOf(rmiPort) + "\n"); 
    output.flush(); 

    input.close(); 
    output.close(); 

    return connectionToken; 
}