每当我尝试发布到https端点时,我都会得到一个javax.net.ssl.SSLException:java.lang.NullPointerException:
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.HttpClient;
try {
MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
HttpClient httpClient = new HttpClient(connectionManager);
PostMethod pm = new PostMethod("https://www.random.org");
httpClient.executeMethod(pm);
} catch (Exception e) {
e.printStackTrace();
}
这给了我:
javax.net.ssl.SSLException: java.lang.NullPointerException
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:190)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1731)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1692)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1675)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1601)
at com.sun.net.ssl.internal.ssl.AppOutputStream.write(AppOutputStream.java:94)
at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:65)
at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:123)
at org.apache.commons.httpclient.HttpConnection.flushRequestOutputStream(HttpConnection.java:828)
at org.apache.commons.httpclient.MultiThreadedHttpConnectionManager$HttpConnectionAdapter.flushRequestOutputStream(MultiThreadedHttpConnectionManager.java:1565)
at org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.java:2116)
at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:1096)
at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:398)
at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171)
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397)
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:323)
at <My File>
Caused by: java.lang.NullPointerException
at org.bouncycastle.jce.provider.JCEECPublicKey.<init>(Unknown Source)
at org.bouncycastle.jce.provider.JDKKeyFactory.createPublicKeyFromPublicKeyInfo(Unknown Source)
at org.bouncycastle.jce.provider.X509CertificateObject.getPublicKey(Unknown Source)
at sun.security.validator.PKIXValidator.initCommon(PKIXValidator.java:92)
at sun.security.validator.PKIXValidator.<init>(PKIXValidator.java:60)
at sun.security.validator.Validator.getInstance(Validator.java:161)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.getValidator(X509TrustManagerImpl.java:108)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:204)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:249)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1185)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:136)
at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:593)
at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:529)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:925)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1170)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:637)
at com.sun.net.ssl.internal.ssl.AppOutputStream.write(AppOutputStream.java:89)
我没有专门在我的机器上配置SSL,但我运行的JSSE测试脚本似乎表明它已安装。我是否可以跳过必要的步骤? NullPointerException让我觉得这可能是一个错误,而不是预期的错误。
编辑2012年5月15日:
我使用eclipse调试器进行了一些深入研究,直到我可以在SSLSocketFactoryImpl中看到证书。
SchemeSocketFactory socketfac = httpClient.getConnectionManager().getSchemeRegistry().getScheme("https").getSchemeSocketFactory();
socketfac.socketfactory.context.trustManager.trustedCerts.map.table, in debugger.
我可以找到我想要点击的网站的证书;事情是,在这个过程中,表中有一个空指针异常。 (参见附图。)如果我使用调试器删除我的条目集中产生NPE的2个(183个)条目,我的代码运行得非常好,但这似乎不是一个可行的解决方案。我不认为这是我的密钥库本身的问题 - 如果我使用keytool -list -keystore cacerts
,它输出183个条目,并且每个条目似乎都被正确格式化。
答案 0 :(得分:1)
最后成功地找出答案。我使用Maven作为另一个工件的一部分,包括bouncycastle 133版本。我的解决方案是在我的maven pom.xml文件中将bouncycastle的versionId升级到140.
答案 1 :(得分:1)
版本133 is about 6 years old。有a number of fixes since。最新版本为1.47,可在org.bouncycaste
group ID (no longer bouncycastle
)下找到。如果您查看发行说明,则会有许多错误修复导致NullPointerException
s。
我还怀疑某些代码在不需要时使用BouncyCastle提供程序而不是Sun提供程序,无论是显式还是因为BC提供程序是在使用Security.insertProviderAt(...)
的默认Sun / Oracle提供程序之前插入的。 / p>
答案 2 :(得分:0)
该代码适合我。启用调试日志以查看正在进行的操作。
java.util.logging.Logger.getLogger("org.apache.http.wire").setLevel(java.util.logging.Level.FINEST);
java.util.logging.Logger.getLogger("org.apache.http.headers").setLevel(java.util.logging.Level.FINEST);
System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.SimpleLog");
System.setProperty("org.apache.commons.logging.simplelog.showdatetime", "true");
System.setProperty("org.apache.commons.logging.simplelog.log.httpclient.wire", "debug");
System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.http", "debug");
System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.http.headers", "debug");