我的问题我跟随:我有两个由maven建造的罐子。一个jar包含一个逻辑,当URL中的scheme为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;
}
注意部分secConfig.getSslTrustStore(),因为它包含传入此方法的InputStream,在jar中从jar获取它之后,它是包含上述代码的jar的父类。获取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中的keystore资源加载给出InputStream的trustore它可以工作,但是如果另一个jar负责向包含prepareSSLSocketFactory的依赖jar提供InputStream(带有keystore)( ) - 它抛出异常。 不知道如何处理它。
请注意,我已经检查了提供资源的类和包含prepareSSLSocketFacory的类是否由同一个ClassLoader通过调用加载:
this.getClass()。getClassLoader()。equals(HttpConnector.class.getClassLoader()) - 没问题。
从类中提供密钥库InputStream到底层的https请求制作类。
但是我不知道是否有可能HttpConnector.class.getClassLoader()返回的ClassLoader不是加载最后在运行时使用的HttpConnector的类。
答案 0 :(得分:0)
问题现在已经解决了......更重要的是 - 答案并非真实。问题与加载相同密钥库资源的不同类加载器无关,实际上资源之一(通过资源我的意思是keytool生成的密钥库文件)在运行时被简单地损坏(因此异常“密钥库格式无效”是可以的)。这很难解决,因为密钥库只生成一次,然后文件被复制到资源文件夹。所以我假设它不会被破坏 - 它不是 - 因为我重建项目 - 在我的maven构建中我有一个资源插件,它为所有资源启用了过滤 - 这使得每次我构建项目时密钥库文件都被破坏了:)