私の問題は次のとおりです。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 をロードするものではない可能性があるかどうかはわかりません。