将jar文件动态加载到ClassPath - HTTPS url?

时间:2014-05-07 09:46:39

标签: java url https classloader

我在ytday事实上遇到了问题。我试图在运行时通过https url动态加载一个jar文件 - 我无法弄清楚如何正确地做到这一点。我能够在标准的http:url上加载jar,但在使用https:

时却没有
public void addURL(URL https) throws IOException {
    HttpsURLConnection conn = (HttpsURLConnection) https.openConnection();


    Class<?>[] parameters = new Class[]{URL.class}; 
    log.info("https url : " + https);


    // IMPORTANT: MUST use the webapp classloader - so derived extension classes car esolve their base classes
    ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();        
    // cast to a URL class loader so we can additional JAR(s) to the search path
    URLClassLoader webappClassLoader = (URLClassLoader)contextClassLoader;  
    Class<?> sysclass = URLClassLoader.class;

    Method method;
    try {
        method = sysclass.getDeclaredMethod("addURL", parameters);
        method.setAccessible(true);
        method.invoke(webappClassLoader, new Object[]{ https });
    } catch (NoSuchMethodException | SecurityException e) {
        e.printStackTrace();
    } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
        e.printStackTrace();
    }
}

非常感谢:)指点/向我显示添加的地点或内容等。

1 个答案:

答案 0 :(得分:1)

由于您正在处理Secure Connections,因此您正在进入证书区域。

Java认为您的服务器不受信任。你可以从堆栈跟踪中了解它。

这里有两个选择。您可以让程序忽略证书验证。在调用addURL之前,您只需要执行一次此代码。

import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import javax.net.ssl.*;

private TrustManager[] getBypassingTrustManager()
{
    TrustManager[] certs = new TrustManager[]
        {
            new X509TrustManager()
            {
                public X509Certificate[] getAcceptedIssuers()
                {
                    return null;
                }

                public void checkClientTrusted(X509Certificate[] certs, String t)
                {
                }

                public void checkServerTrusted(X509Certificate[] certs, String t)
                {
                }
            }
        };
    return certs;
}


SSLContext sslCtx = SSLContext.getInstance("SSL");
TrustManager trustManager[] = getBypassingTrustManager();
sslCtx.init(null, trustManager, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sslCtx.getSocketFactory());

上述方法在安全意义上并不是很好。如果您了解Java Keystores如何工作(java.security.KeyStore),那就更好了。您可以将证书从服务器保存在密钥库文件中,而不是忽略证书验证。然后,您的应用程序可以加载密钥库,这使Java信任您的服务器。