OpenJDK ARM上的HTTP SSL请求问题

时间:2015-01-19 19:38:57

标签: java https openjdk

我一直在研究用Linux(x86)运行的Java编写的程序多年,现在将其移植到Linux(ARM)上。我正面临一个问题,不知道它来自哪里。

使用

在Slackware 12.1(x86)上运行示例时
# java -version
java version "1.6.0_11"
Java(TM) SE Runtime Environment (build 1.6.0_11-b03)
Java HotSpot(TM) Client VM (build 11.0-b16, mixed mode, sharing)

它运行得非常好。使用

在Slackware 14.1(ARM)上运行时
# java -version
java version "1.7.0_13"
OpenJDK Runtime Environment (IcedTea7 2.3.6) (Slackware)
OpenJDK Zero VM (build 22.0-b10, mixed mode)

我得到一个例外:

# java -jar SpectoTechnologies_TestHTTP.jar
java.security.ProviderException: Error parsing configuration
        at sun.security.pkcs11.Config.getConfig(Config.java:88)
        at sun.security.pkcs11.SunPKCS11.<init>(SunPKCS11.java:128)
        at sun.security.pkcs11.SunPKCS11.<init>(SunPKCS11.java:103)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
        at sun.security.jca.ProviderConfig$2.run(ProviderConfig.java:224)
        at sun.security.jca.ProviderConfig$2.run(ProviderConfig.java:206)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.security.jca.ProviderConfig.doLoadProvider(ProviderConfig.java:206)
        at sun.security.jca.ProviderConfig.getProvider(ProviderConfig.java:187)
        at sun.security.jca.ProviderList.getProvider(ProviderList.java:232)
        at sun.security.jca.ProviderList$ServiceList.tryGet(ProviderList.java:433)
        at sun.security.jca.ProviderList$ServiceList.access$200(ProviderList.java:375)
        at sun.security.jca.ProviderList$ServiceList$1.hasNext(ProviderList.java:485)
        at sun.security.jca.GetInstance.getInstance(GetInstance.java:170)
        at javax.net.ssl.SSLContext.getInstance(SSLContext.java:156)
        at javax.net.ssl.SSLContext.getDefault(SSLContext.java:97)
        at javax.net.ssl.SSLSocketFactory.getDefault(SSLSocketFactory.java:121)
        at javax.net.ssl.HttpsURLConnection.getDefaultSSLSocketFactory(HttpsURLConnection.java:333)
        at javax.net.ssl.HttpsURLConnection.<init>(HttpsURLConnection.java:291)
        at sun.net.www.protocol.https.HttpsURLConnectionImpl.<init>(HttpsURLConnectionImpl.java:85)
        at sun.net.www.protocol.https.Handler.openConnection(Handler.java:62)
        at java.net.URL.openConnection(URL.java:1020)
        at com.spectotechnologies.tests.HTTP.main(HTTP.java:30)
Caused by: sun.security.pkcs11.ConfigurationException: name must be specified
        at sun.security.pkcs11.Config.parse(Config.java:465)
        at sun.security.pkcs11.Config.<init>(Config.java:216)
        at sun.security.pkcs11.Config.getConfig(Config.java:84)
        ... 25 more

问题很可能与Oracle / Sun JRE与OpenJDK的代码不兼容......或Linux上缺少的东西(SSL包或其他东西)有关,但找不到类似的东西的答案。

我已经制作了一个SSCCE来重现这个问题:

package com.spectotechnologies.tests;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringWriter;
import java.io.Writer;
import java.net.HttpURLConnection;
import java.net.Proxy;
import java.net.URL;

/**
 *
 * @author Alexandre Lavoie
 */
public class HTTP
{
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args)
    {
        try
        {
            InputStream oInput;
            URL oURL = new URL("https://google.com");

            HttpURLConnection oConnection = (HttpURLConnection)oURL.openConnection(Proxy.NO_PROXY);

            oConnection.setDoOutput(true);
            oConnection.setDoInput(true);
            oConnection.setRequestMethod("GET");

            if(oConnection.getResponseCode() != 500)
            {
                oInput = oConnection.getInputStream();
            }
            else
            {
                oInput = oConnection.getErrorStream();
            }

            String sResult = convertStreamToString(oInput);

            System.out.println(sResult);
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }

    }

    public static String convertStreamToString(java.io.InputStream is) throws IOException
    {
        if(is != null)
        {
            Writer writer = new StringWriter();

            char[] buffer = new char[1024];

            try
            {
                Reader reader = new BufferedReader(new InputStreamReader(is,"utf-8"));
                int n;

                while ((n = reader.read(buffer)) != -1)
                {
                    writer.write(buffer, 0, n);
                }
            }
            finally
            {
                is.close();
            }

            return writer.toString();
        }
        else
        {
            return "";
        }
    }
}

1 个答案:

答案 0 :(得分:0)

解析配置文件$JAVA_HOME/lib/security/java.security时会引发错误。有几个错误与此有关。

java.security.ProviderException: Error parsing configuration with space

sun.security.pkcs11.ConfigurationException: Unexpected value Token ['(']

我的猜测是你的配置文件中有特殊字符或空格,这些字符或空格在jvm的一个版本中正确解释,而在另一个版本中没有。