0

私の問題は次のとおりです。mavenによってビルドされた2つのjarファイルがあります。1 つの jar には、URL のスキームが https の場合に、jave.net.ssl からいくつかのクラスをラップして https 要求を行うロジックが含まれています。 HttpsUrlConnection を取得した後、次のように SSLSocketFactory を取得しています。

private SSLSocketFactory prepareSSLSocketFactory(SecurityConfig secConfig) throws NoSuchAlgorithmException, CertificateException, IOException, KeyStoreException, KeyManagementException
{
    if (secConfig == null) throw new IllegalArgumentException("secConfig");
    if (sslSocketFactory!=null)
        return sslSocketFactory;

    KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());      
    trustStore.load(secConfig.getSslTrustStore()/*ClassLoader.getSystemClassLoader().getResourceAsStream("jclienttruststore.jks")*/, secConfig.getSslTrustStorePassword().toCharArray());

    TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
    tmf.init(trustStore);
    SSLContext ctx = SSLContext.getInstance(secConfig.getSslAlgorithm());
    ctx.init(null, tmf.getTrustManagers(), null);
    sslSocketFactory = ctx.getSocketFactory();
    return sslSocketFactory;
}

上記のコードを含むものの親である jar からクラスで取得した後、このメソッドに渡された InputStream が含まれているため、部分 secConfig.getSslTrustStore() に注意してください。InputStream の取得は次のとおりです。

protected InputStream obtainTrustStore() 
{                
    //InputStream stream = this.getClass().getClassLoader().getParent().getResourceAsStream("trustcert/jclienttruststore.jks");
    //InputStream stream = ClassLoader.getSystemClassLoader().getResourceAsStream("trustcert/jclienttruststore.jks");

    InputStream stream = this.getClass().getClassLoader().getResourceAsStream("trustcert/jclienttruststore.jks");
    return stream;
}       

リソースが正常に配置され、InputStream が取得されます。しかし、最初のスニペットで trustStore.load() を実行すると、KeyStoreFormat が無効であるという奇妙な例外が発生します。KeyStoreFormat は有効です - これは確かです - この prepareSSLSocketFactory を含む jar からテスト メソッドを実行し、現在の jar のリソースにある同じキーストア ファイルをロードすると、例外はまったくなく、クライアントは SSL 経由で正常に通信します。

したがって、私の観察は次のとおりです。メソッドprepareSSLSocketFactoryを実行したjarにあるキーストアリソースからInputStreamを提供するトラストアをロードすると機能しますが、別のjarがprepareSSLSocketFactory()を含む依存jarにInputStream(キーストア付き)を提供する責任がある場合-それ例外をスローします。それに対処する方法がわからない。

リソースを提供するクラスと prepareSSLSocketFacory を含むクラスが、次の呼び出しによって同じ ClassLoader によってロードされているかどうかを確認したことに注意してください。

this.getClass().getClassLoader().equals(HttpConnector.class.getClassLoader()) - 大丈夫です。

キーストア InputStream を提供するクラスから、基になる https リクエスト作成クラスに。

ただし、HttpConnector.class.getClassLoader() によって返される ClassLoader が、実行時に最後に使用される HttpConnector をロードするものではない可能性があるかどうかはわかりません。

4

1 に答える 1

0

問題は解決されました...さらに、答えは現実的ではありません。この問題は、同じキーストア リソースをロードする別のクラスローダーとは関連していませんでした。実際、リソースの 1 つ (リソースとは、keytool によって生成されたキーストア ファイルを意味します) が実行時に単純に破損していました (そのため、「キーストア フォーマットが無効です」という例外は問題ありませんでした)。キーストアが 1 回だけ生成され、その後ファイルがリソース フォルダーにコピーされたため、これを理解するのは非常に困難でした。したがって、プロジェクトを再構築して以来、破損することはないと想定していました-そうではありませんでした-私のmavenビルドでは、すべてのリソースに対してフィルタリングが有効になっているリソースプラグインがありました-これにより、プロジェクトをビルドするたびにキーストアファイルが破損していました:)

于 2012-11-18T00:53:16.843 に答える