【问题标题】:Error accessing a Web Service with SSL使用 SSL 访问 Web 服务时出错
【发布时间】:2011-02-16 02:19:28
【问题描述】:

我有一个程序应该将文件发送到需要 SSL 连接的 Web 服务。我运行程序如下:

SET JAVA_HOME=C:\Program Files\Java\jre1.6.0_07
SET com.ibm.SSL.ConfigURL=ssl.client.props
"%JAVA_HOME%\bin\java" -cp ".;Test.jar" ca.mypackage.Main

这很好用,但是当我将第一行更改为

SET JAVA_HOME=C:\Program Files\IBM\SDP\runtimes\base_v7\java\jre

我收到以下错误:

com.sun.xml.internal.ws.client.ClientTransportException: HTTP transport error: java.net.SocketException: java.lang.ClassNotFoundException: Cannot find the specified class com.ibm.websphere.ssl.protocol.SSLSocketFactory
at com.sun.xml.internal.ws.transport.http.client.HttpClientTransport.getOutput(HttpClientTransport.java:119)
at com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.process(HttpTransportPipe.java:140)
at com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.processRequest(HttpTransportPipe.java:86)
at com.sun.xml.internal.ws.api.pipe.Fiber.__doRun(Fiber.java:593)
at com.sun.xml.internal.ws.api.pipe.Fiber._doRun(Fiber.java:552)
at com.sun.xml.internal.ws.api.pipe.Fiber.doRun(Fiber.java:537)
at com.sun.xml.internal.ws.api.pipe.Fiber.runSync(Fiber.java:434)
at com.sun.xml.internal.ws.client.Stub.process(Stub.java:247)
at com.sun.xml.internal.ws.client.sei.SEIStub.doProcess(SEIStub.java:132)
at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:242)
at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:222)
at com.sun.xml.internal.ws.client.sei.SEIStub.invoke(SEIStub.java:115)
at $Proxy26.fileSubmit(Unknown Source)
at com.testing.TestingSoapProxy.fileSubmit(TestingSoapProxy.java:81)
at ca.mypackage.Main.main(Main.java:63)
Caused by: java.net.SocketException: java.lang.ClassNotFoundException: Cannot find the specified class com.ibm.websphere.ssl.protocol.SSLSocketFactory
at javax.net.ssl.DefaultSSLSocketFactory.a(SSLSocketFactory.java:7)
at javax.net.ssl.DefaultSSLSocketFactory.createSocket(SSLSocketFactory.java:1)
at com.ibm.net.ssl.www2.protocol.https.c.afterConnect(c.java:110)
at com.ibm.net.ssl.www2.protocol.https.d.connect(d.java:14)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:902)
at com.ibm.net.ssl.www2.protocol.https.b.getOutputStream(b.java:86)
at com.sun.xml.internal.ws.transport.http.client.HttpClientTransport.getOutput(HttpClientTransport.java:107)
... 14 more
Caused by: java.lang.ClassNotFoundException: Cannot find the specified class com.ibm.websphere.ssl.protocol.SSLSocketFactory
at javax.net.ssl.SSLJsseUtil.b(SSLJsseUtil.java:20)
at javax.net.ssl.SSLSocketFactory.getDefault(SSLSocketFactory.java:36)
at javax.net.ssl.HttpsURLConnection.getDefaultSSLSocketFactory(HttpsURLConnection.java:16)
at javax.net.ssl.HttpsURLConnection.<init>(HttpsURLConnection.java:36)
at com.ibm.net.ssl.www2.protocol.https.b.<init>(b.java:1)
at com.ibm.net.ssl.www2.protocol.https.Handler.openConnection(Handler.java:11)
at java.net.URL.openConnection(URL.java:995)
at com.sun.xml.internal.ws.api.EndpointAddress.openConnection(EndpointAddress.java:206)
at com.sun.xml.internal.ws.transport.http.client.HttpClientTransport.createHttpConnection(HttpClientTransport.java:277)
at com.sun.xml.internal.ws.transport.http.client.HttpClientTransport.getOutput(HttpClientTransport.java:103)
... 14 more

所以看起来这个问题与我正在使用的 JRE 有关,但似乎没有意义的是非 IBM JRE 工作正常,但 IBM JRE 没有。有什么想法或建议吗?

【问题讨论】:

    标签: java web-services ssl ibm-jdk ibm-jvm


    【解决方案1】:

    当我的 Batch 应用程序尝试使用 Apache wink 从 Restful Web 服务获取数据时,我遇到了类似的问题。我使用 MyEclipse 作为我的开发环境。并且使用的是IBM webSphere 8.5提供的jre。当我更改为 Sun 1.6 jre 后,问题得到了解决。

    【讨论】:

      【解决方案2】:

      在搜索相同的错误消息时发现了此主题,但找到了不同的解决方案。 使用 Apache Wink 客户端测试 https REST 服务:

      ClientConfig config = new ClientConfig();
      config.setBypassHostnameVerification(true);
      RestClient client = new RestClient(config);
      

      并将工厂设置为空:

      Security.setProperty("ssl.SocketFactory.provider", "");
      Security.setProperty("ssl.ServerSocketFactory.provider", "");
      

      我的运行时是使用 IBM WebSphere v8.5.5 中的 IBM JRE 1.7 进行的独立 Camel 测试。

      【讨论】:

        【解决方案3】:

        Java 只允许一个用于 JVM 的 SSL 连接工厂类。如果您使用的是随 WebSphere Application Server v6x/7x/8x 或 Rational Application Developer 中的任何其他 WebSphere 服务器工具一起提供的 JDK,那么那些需要来自 WebSphere Application 的 IBM ( com.ibm.websphere.ssl.protocol.SSLSocketFactory ) 特定类服务器运行时。 因为 java 安全文件的 JSSE 套接字工厂设置如下

        # Default JSSE socket factories
        #ssl.SocketFactory.provider=com.ibm.jsse2.SSLSocketFactoryImpl
        #ssl.ServerSocketFactory.provider=com.ibm.jsse2.SSLServerSocketFactoryImpl
        
        # WebSphere socket factories (in cryptosf.jar)
        ssl.SocketFactory.provider=com.ibm.websphere.ssl.protocol.SSLSocketFactory
        ssl.ServerSocketFactory.provider=com.ibm.websphere.ssl.protocol.SSLServerSocketFactory
        

        因此,如果您取消注释 Default JSSE Socket 工厂并注释掉 WebSphere 工厂,那么 WAS 将会呕吐。

        更好的解决方法是在您的类路径中包含 com.ibm.ws.security.crypto.jar 文件。此 jar 文件依赖于 com.ibm.ffdc.jar 文件,因此您需要在类路径中使用它。这两个 jarfile 都可以在 &lt;WebSphere_Install_Dirctory&gt;/plugins/ 下获得

        【讨论】:

        • 我可能很幸运,但使用默认 JSSE 套接字工厂(WebSphere 已被注释掉)似乎对我有用。现在我可以在我的 CI 构建中使用 JDK。
        【解决方案4】:

        另一个似乎对我有用的“解决方案”。创建您自己的安全属性文件,my.java.security,其内容如下:

        ssl.SocketFactory.provider=
        ssl.ServerSocketFactory.provider=
        

        在调用 Java(或者在我的例子中是 maven)时,添加命令行选项:

        -Djava.security.properties=C:\myfiles\my.java.security
        

        摘自 IBM Liberty 文档:http://www-01.ibm.com/support/knowledgecenter/was_beta_liberty/com.ibm.websphere.wlp.nd.multiplatform.doc/ae/rwlp_trouble.html?lang=en

        【讨论】:

        • 确保 JDK 下 java.security 文件中的 security.overrideProperties=true 允许覆盖
        【解决方案5】:

        可以通过取消注释以下 JSSE 属性,在 WAS_HOME/*/java/jre/lib/security/java.security 文件中设置这些属性。

        默认 JSSE 套接字工厂

        ssl.SocketFactory.provider=com.ibm.jsse2.SSLSocketFactoryImpl ssl.ServerSocketFactory.provider=com.ibm.jsse2.SSLServerSocketFactoryImpl

        【讨论】:

        • 你需要注释掉后面的 websphere 。
        【解决方案6】:

        尝试在设置代码中的某处添加这两行:

        Security.setProperty("ssl.SocketFactory.provider", "com.ibm.jsse2.SSLSocketFactoryImpl");
        Security.setProperty("ssl.ServerSocketFactory.provider", "com.ibm.jsse2.SSLServerSocketFactoryImpl");
        

        【讨论】:

        • 我已经这样做了,现在我得到了以下异常:java.security.KeyStoreException:IBMKeyManager:访问密钥库时出现问题 java.io.IOException:密钥库被篡改,或者密码不正确。看来我需要把“changeme”放在某个地方?
        【解决方案7】:

        如果您的非 IBM jre 是 sun,那么它已经附带了 SSL 类实现。

        IBM jre 似乎根本不包含 SSL 实现类。

        【讨论】:

        • 澄清一下,因为它有点不正确。有问题的 JRE 是 WAS JRE。每个 IBM JRE 都包含 SSL 类,但是这个类不应该用于独立的 Java 程序,它包含用于 SSL 提供程序的配置,该提供程序包含在 WAS 库中。如果您在没有 WebSphere 的情况下使用它,则需要从 java.security 覆盖 ssl.SocketFactory.providerssl.ServerSocketFactory.provider
        猜你喜欢
        • 1970-01-01
        • 2010-10-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-02-05
        相关资源
        最近更新 更多