1

Twitter4Jを使用してTwitterストリーミングAPIからツイートを取得しようとしています。プロジェクトはSSLSocketを使用してリモートサーバーに接続し、データを取得します。その後、Twitter4Jが呼び出されます。問題は、この接続を確立すると、Twitter4Jで次の例外が発生することです。

[Wed Feb 20 11:32:02 CET 2013] sun.security.validator.ValidatorException:PKIXパスの構築に失敗しました:sun.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...

私の実際のプロジェクトでは、壊れているので同じことをすることはできません...ほとんどすべて^^

何が問題なのですか?と解決策?

4

1 に答える 1

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;
}
于 2013-02-21T10:02:21.730 に答える