初始化默认 SSL 上下文失败
Posted
技术标签:
【中文标题】初始化默认 SSL 上下文失败【英文标题】:Failure initializing default SSL context 【发布时间】:2012-04-08 15:15:57 【问题描述】:我的httpclient项目遇到了一个奇怪的问题。它在其他两个使用java1.6的Centos系统上运行成功。但它在另一台机器(centos 和 java1.6)上失败了。问题是:
java.lang.IllegalStateException: [java] 在 org.apache.http.conn.ssl.SSLSocketFactory.createDefaultSSLContext(SSLSocketFactory.java:211) [java] 在 org.apache.http.conn.ssl.SSLSocketFactory.(SSLSocketFactory.java:333) [java] 在 org.apache.http.conn.ssl.SSLSocketFactory.getSocketFactory(SSLSocketFactory.java:165) [java] 在 org.apache.http.impl.conn.SchemeRegistryFactory.createDefault(SchemeRegistryFactory.java:45) [java] 在 org.apache.http.impl.client.AbstractHttpClient.createClientConnectionManager(AbstractHttpClient.java:294) [java] 在 org.apache.http.impl.client.AbstractHttpClient.getConnectionManager(AbstractHttpClient.java:445) [java] at simulativeLogin.WebClientDevWrapper.wrapClient(Unknown Source) [java] at simulativeLogin.GetAccessToken.getToken(Unknown Source) [java] 在 crawler.FriendshipCrawler.main(未知来源) [java] 在 java.lang.reflect.Method.invoke(libgcj.so.10) [java] 在 org.apache.tools.ant.taskdefs.ExecuteJava.run(ant-1.7.1.jar.so) [java] 在 org.apache.tools.ant.taskdefs.ExecuteJava.execute(ant-1.7.1.jar.so) [java] 在 org.apache.tools.ant.taskdefs.Java.run(ant-1.7.1.jar.so) [java] 在 org.apache.tools.ant.taskdefs.Java.executeJava(ant-1.7.1.jar.so) [java] 在 org.apache.tools.ant.taskdefs.Java.executeJava(ant-1.7.1.jar.so) [java] 在 org.apache.tools.ant.taskdefs.Java.execute(ant-1.7.1.jar.so) [java] 在 org.apache.tools.ant.UnknownElement.execute(ant-1.7.1.jar.so) [java] 在 java.lang.reflect.Method.invoke(libgcj.so.10) [java] 在 org.apache.tools.ant.dispatch.DispatchUtils.execute(ant-1.7.1.jar.so) [java] 在 org.apache.tools.ant.Task.perform(ant-1.7.1.jar.so) [java] 在 org.apache.tools.ant.Target.execute(ant-1.7.1.jar.so) [java] 在 org.apache.tools.ant.Target.performTasks(ant-1.7.1.jar.so) [java] 在 org.apache.tools.ant.Project.executeSortedTargets(ant-1.7.1.jar.so) [java] 在 org.apache.tools.ant.Project.executeTarget(ant-1.7.1.jar.so) [java] 在 org.apache.tools.ant.helper.DefaultExecutor.executeTargets(ant-1.7.1.jar.so) [java] 在 org.apache.tools.ant.Project.executeTargets(ant-1.7.1.jar.so) [java] 在 org.apache.tools.ant.Main.runBuild(ant-1.7.1.jar.so) [java] 在 org.apache.tools.ant.Main.startAnt(ant-1.7.1.jar.so) [java] 在 org.apache.tools.ant.launch.Launcher.run(ant-launcher-1.7.1.jar.so) [java] 在 org.apache.tools.ant.launch.Launcher.main(ant-launcher-1.7.1.jar.so) [java] 引起:java.lang.IllegalStateException [java] 在 gnu.javax.net.ssl.provider.X509KeyManagerFactory.engineGetKeyManagers(libgcj.so.10) [java] 在 javax.net.ssl.KeyManagerFactory.getKeyManagers(libgcj.so.10) [java] 在 org.apache.http.conn.ssl.SSLSocketFactory.createSSLContext(SSLSocketFactory.java:187) [java] 在 org.apache.http.conn.ssl.SSLSocketFactory.createDefaultSSLContext(SSLSocketFactory.java:209)【问题讨论】:
这是线索:由IllegalStateException
gnu.javax.net.ssl.provider.X509KeyManagerFactory.engineGetKeyManagers
in libgcj.so.10
引起。
对于我自己,我只是想“gcj?你的问题就在那里!”但我想这对你来说不是一个有用的答案……
问题已解决。 javac 的版本是 1.5,但 open-jdk 的版本是 1.6。匹配版本后问题消失。
@DonalFellows,你应该为此写一个答案。 Lujingsun,这不仅仅是 Java 的版本,还有 JRE 实现及其安全提供程序,特别是您明显使用的是 GCJ 实现,而不是 OpenJDK。
【参考方案1】:
这不是你的错。使用另一个JVM,这将解决您的问题。我有同样的问题。我在 Gumstix/linux/jamVM 上运行 Apache HttpClient。我得到了完全相同的例外。这是X509的测试程序。我在我的 Mac mini 上运行它,结果是“SunX509”作为算法;但在 jamVM 上,它是“空的”。试试看。
public class TestX509
public static void main(String[] args)
String algorithm = Security
.getProperty("ssl.KeyManagerFactory.algorithm");
System.out.println("algorithm is " + algorithm);
参见 gnu.javax.net.ssl.provider.X509KeyManagerFactory.java 第 108 行的源代码。这就是异常的来源。 (因为 'current' 是一个密钥管理器,它是空的。你从前面的测试中知道。)
104: protected KeyManager[] engineGetKeyManagers()
105:
106: if (current == null)
107:
108: throw new IllegalStateException();
109:
110: return new KeyManager[] current ;
111:
112:
由于库抛出IllegalStateException,这是一个RuntimeException,有人认为这是GCJ的一个错误,并在此报告http://code.google.com/p/selenium/issues/detail?id=2483。
【讨论】:
【参考方案2】:我看到您使用 GCJ 作为 Java 的实现(因为原因异常源自 gnu.javax.net.ssl.provider.X509KeyManagerFactory
类,以及许多堆栈级别在 libgcj.so.10
中的方式)。不幸的是,这不是官方认可的 Java 版本。它在其实施的几个方面存在许多问题,有时可能会非常棘手。特别是 X.509 密钥处理似乎有问题! (我不知道它确实如此,但它显然如此。)
最简单的解决方法是切换到使用不同的 Java 实现。 Sun/Oracle Java 实现绝对不错(我广泛使用它),而且我也听说过有关 OpenJDK 实现的好消息;据我了解,OpenJDK 是删除了某些部分的 Sun JDK(特别是他们从其他地方获得许可的位,我 相信 是编解码器和 GUI 代码的一部分,但我不肯定知道)。您不想做的是花时间解决没有人推荐使用的 Java 实现中的错误!
【讨论】:
我也不知道gcj实现了1.6的API;我会更加多疑……【参考方案3】:答案就在 cmets 中。如果您确实输入了java -version
并看到java version "1.5.0"
,则需要确保您使用的是Java 6。它应该是java version "1.6.0"
【讨论】:
以上是关于初始化默认 SSL 上下文失败的主要内容,如果未能解决你的问题,请参考以下文章
由于已经存在根应用程序上下文,无法初始化上下文,因此在 tomcat 中部署战争失败
上下文初始化失败:org.springframework.beans.factory.BeanDefinitionStoreException