当前位置: 首页 > 面试题库 >

Apache HttpClient在macOS上因Java 11失败

高胜
2023-03-14
问题内容

我正在尝试将我的代码从Java 8迁移到Java 11,此代码…

 private static String  readMultiHttpsUrlResultAsString(List<String> mbRecordingIds, String level) throws Exception
{
    String result = "";
    class NaiveTrustStrategy implements TrustStrategy
    {
        @Override
        public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException
        {
            return true;
        }
    };

    SSLContext sslcontext = org.apache.http.ssl.SSLContexts.custom()
            .loadTrustMaterial(new NaiveTrustStrategy())
            .build();

    CloseableHttpClient httpclient = HttpClients.custom()
            .setSSLSocketFactory(new SSLConnectionSocketFactory(sslcontext))
            .build();

    StringBuilder sb = new StringBuilder("?recording_ids=");
    for(String next:mbRecordingIds)
    {
        sb.append(next + ";");
    }
    sb.setLength(sb.length() - 1);
    try
    {
        String url = "https://acousticbrainz.org/api/v1"+level+sb;
        HttpGet httpget = new HttpGet(url);

        try (CloseableHttpResponse response = httpclient.execute(httpget);)
        {
            int statusCode = response.getStatusLine().getStatusCode();
            if(statusCode!=HttpURLConnection.HTTP_OK)
            {
                return "";
            }
            HttpEntity entity = response.getEntity();
            result = EntityUtils.toString(entity);
            EntityUtils.consume(entity);
        }
    }
    finally
    {
        httpclient.close();
    }
    return result;
}

}

在MacOS上使用(AdoptOpenJdk)Java 11.0.6失败了,

SSLContext sslcontext = org.apache.http.ssl.SSLContexts.custom()
            .loadTrustMaterial(new NaiveTrustStrategy())
            .build();

它可以在Windows上正常运行(也使用AdoptOpenJdk Java
11.0.6)。一个区别是Windows版本使用从带有jlink的jdk构建的cutdown jre,而MacOS版本使用AdoptOpenJDk
jre构建。MacOS版本是使用InfiniteKinds分支创建的AppBundler

这是堆栈跟踪:

java.lang.NoClassDefFoundError: Could not initialize class sun.security.ssl.SSLContextImpl$TLSContext
    at java.base/java.lang.Class.forName0(Native Method)
    at java.base/java.lang.Class.forName(Class.java:315)
    at java.base/java.security.Provider$Service.getImplClass(Provider.java:1848)
    at java.base/java.security.Provider$Service.newInstance(Provider.java:1824)
    at java.base/sun.security.jca.GetInstance.getInstance(GetInstance.java:236)
    at java.base/sun.security.jca.GetInstance.getInstance(GetInstance.java:164)
    at java.base/javax.net.ssl.SSLContext.getInstance(SSLContext.java:168)
    at org.apache.http.ssl.SSLContextBuilder.build(SSLContextBuilder.java:269)
    at com.jthink.songkong.analyse.acousticbrainz.AcousticBrainz.readMultiHttpsUrlResultAsString(AcousticBrainz.java:409)
    at com.jthink.songkong.analyse.acousticbrainz.AcousticBrainz.readLowLevelData(AcousticBrainz.java:373)

我正在使用Apache Httpclient 4.5.3,并且正在使用此lib,因为我是从需要使用ssl的Web服务获取数据的。

更新
我从下面的答案中将示例测试添加到了我的源代码中,并修改了我的构建,以使其在运行应用程序时成为开始类,并为我提供了该堆栈跟踪信息(当从命令行open使用内嵌的Java运行时运行捆绑软件时)由infinitekind
appbundler提供的捆绑包)

Exception in thread "main" java.lang.ExceptionInInitializerError
    at java.base/javax.crypto.Cipher.getInstance(Unknown Source)
    at java.base/sun.security.ssl.JsseJce.getCipher(Unknown Source)
    at java.base/sun.security.ssl.SSLCipher.isTransformationAvailable(Unknown Source)
    at java.base/sun.security.ssl.SSLCipher.<init>(Unknown Source)
    at java.base/sun.security.ssl.SSLCipher.<clinit>(Unknown Source)
    at java.base/sun.security.ssl.CipherSuite.<clinit>(Unknown Source)
    at java.base/sun.security.ssl.SSLContextImpl.getApplicableSupportedCipherSuites(Unknown Source)
    at java.base/sun.security.ssl.SSLContextImpl$AbstractTLSContext.<clinit>(Unknown Source)
    at java.base/java.lang.Class.forName0(Native Method)
    at java.base/java.lang.Class.forName(Unknown Source)
    at java.base/java.security.Provider$Service.getImplClass(Unknown Source)
    at java.base/java.security.Provider$Service.newInstance(Unknown Source)
    at java.base/sun.security.jca.GetInstance.getInstance(Unknown Source)
    at java.base/sun.security.jca.GetInstance.getInstance(Unknown Source)
    at java.base/javax.net.ssl.SSLContext.getInstance(Unknown Source)
    at org.apache.http.ssl.SSLContextBuilder.build(SSLContextBuilder.java:389)
    at Example.main(Example.java:23)
Caused by: java.lang.SecurityException: Can not initialize cryptographic mechanism
    at java.base/javax.crypto.JceSecurity.<clinit>(Unknown Source)
    ... 17 more
Caused by: java.lang.SecurityException: Can't read cryptographic policy directory: unlimited
    at java.base/javax.crypto.JceSecurity.setupJurisdictionPolicies(Unknown Source)
    at java.base/javax.crypto.JceSecurity$1.run(Unknown Source)
    at java.base/javax.crypto.JceSecurity$1.run(Unknown Source)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    ... 18 more

这与我以前有过不同,但是也许这是根本原因还是这种误导?

而如果我只是运行java -jar songkong6.9.jar它,那么它将运行Example并打印出 Loaded 没有错误,如果我从/
Library / Java指定完整路径,则它在所有情况下都适用(Java 11 / Java 14 / JDk和JRE)

更新 根据以下答案,我已经取得了一些进展。

安装在MacOS上的JRE包含一个conf文件夹,当使用InfiniteKinds
appbundler将JRE添加到我的捆绑包(SongKong)中时,它没有conf文件夹。它确实有一个lib /
security文件夹,其中包含,default.policy但这似乎还不够。

pauls-Mac-mini:Home paul$ ls -lR lib/security
total 704
-rw-r--r--  1 paul  admin    1253 22 Apr 14:56 blacklisted.certs
-rw-r--r--  1 paul  admin  103147 22 Apr 14:56 cacerts
-rw-r--r--  1 paul  admin    8979 22 Apr 16:01 default.policy
-rw-r--r--  1 paul  admin  233897 22 Apr 14:56 public_suffix_list.dat

安装构建的捆绑包后,如果我手动将conf文件夹从已安装的JRE复制到Java插件的Home文件夹中

例如

/Applications/SongKong.app/Contents/PlugIns/adoptopenjdk-11.jre/Contents/Home

位置,则示例代码和我的原始代码在从bundle中运行时都不会出现错误。

此外,似乎要查找的是无限文件夹及其内容(两个文件实际上是相同的),因此,如果我删除了几个文件,则剩下的就是

pauls-Mac-mini:Home paul$ pwd
/Applications/SongKong.app/Contents/PlugIns/adoptopenjdk-11.jre/Contents/Home
pauls-Mac-mini:Home paul$ ls -lR conf
total 0
drwxr-xr-x  3 paul  admin  96 22 Apr 15:14 security

conf/security:
total 0
drwxr-xr-x  3 paul  admin  96 22 Apr 15:22 policy

conf/security/policy:
total 0
drwxr-xr-x  4 paul  admin  128 22 Apr 15:28 unlimited

conf/security/policy/unlimited:
total 16
-rw-r--r--  1 paul  admin  146 22 Apr 15:06 default_US_export.policy
-rw-r--r--  1 paul  admin  193 22 Apr 15:06 default_local.policy

然后它继续工作。

问题(除了为什么它不能开箱即用之外)是我认为我无法将文件复制到经过硬化的运行时应用程序的此位置,因此我需要将这些策略文件存储在其他位置,以便可以将其作为appbundler构建的一部分进行安装。因此,作为测试,我已重命名conf文件conf.old夹folder并将以下参数添加到捆绑包中

<string>-Djava.security.policy=/Applications/SongKong.app/Contents/PlugIns/adoptopenjdk-11.jre/Contents/Home/conf.old/security/policy/unlimited/default_local.policy</string>

或替换而不是附加策略文件

<string>-Djava.security.policy==/Applications/SongKong.app/Contents/PlugIns/adoptopenjdk-11.jre/Contents/Home/conf.old/security/policy/unlimited/default_local.policy</string>

但这是行不通的,我尝试了各种值,但没有任何效果。唯一有效的方法是将其保留在conf子文件夹中,然后不管是否传递此参数都无关紧要。(我也尝试添加-Dsecurity.manager作为另一个选项,但这只是导致有关html" target="_blank">日志记录权限的新错误。)


问题答案:

最终,在Anish的帮助下,解决了缺少策略文件的问题,而这仅仅是使用AppBunder构建的包的问题。

jdk代码似乎真的希望conf在JRE中有一个文件夹,OpenJDk中有一个文件夹,但没有一次与AppBundler捆绑到我的应用程序中。因此,我下载了最新的AppBundler
src代码并对其进行了重建,然后重新构建了我的appbundle,并对其进行了修复,现在包含conf文件夹,并且应用程序运行时没有错误。



 类似资料:
  • Glumpy在MacOS(10.14)上的安装失败,出现了叮当声错误(triangle也一样,但抛出了相同的错误)。错误是clang找不到stdio。h文件,该文件清楚地显示在系统上。我能告诉你怎么找到stdio的位置吗。h到设置。py脚本? 我曾试图从源代码处编译它,但后来我进入了python的地狱,我希望避免这种情况。Pip将是最佳方式 这就是它失败的地方: clang-fno-严格-混淆现象

  • 在macOS终端中运行时,出现以下错误。 PHP警告:preg_match():JIT编译失败:内存不足phar:///usr/local/bin/composer.phar/vendor/symfony/console/Application.php 在线755 在第755行PHP警告:preg_match():JIT编译失败:没有更多的内存在phar://usr/本地/bin/composer

  • 我有以下配置: MacOS 11.0.1(MacOS防火墙关闭) Android Studio 4.1.2 Android Gradle插件版本4.1.1 Gradle版本6.5 Java jdk版本1.8.0\u 251 Gradle build开始在我的所有项目中报告错误,所以我猜它与特定的项目配置(build.gradle等)无关。 相同的项目在Windows上的相同Android Stud

  • Jersey 1.19.4能在Java11上工作吗? 如果没有,是否有一个与Jersey 1.19.4等效的api支持相同的api,并且仍然可以在Java11上工作?

  • 我正在使用IntelliJ,我想运行一个以前在Linux中运行的JavaFX项目,我导入了库,并使用了vm参数 <代码>--模块路径/用户/frenk/桌面/javafx-sdk-17/lib--添加模块javafx。控件,javafx。fxml 但我一直收到同样的错误 我看到的所有答案都与vm params有关,所以我无法弄清楚可能是什么问题,我使用java 16作为运行时和macOS bigs

  • 本小节我们将介绍如何在 MacOS 平台安装 Java 。 如果你想在其他平台安装 Java,请查看对应平台的安装教程: 在 Windows 上安装 Java 在 Linux 上安装 Java 1. 下载安装包 我们首先打开 Oracle 官网的 JDK 下载地址,找到 Java SE 14 版块,点击 JDK Download 按钮。 点击 JDK Download 按钮后我们会跳转到 JDK