2013-02-20 53 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; 
}