javafx 16 Web 引擎异常 "SSL Handshake failed"

javafx 16 WebEngine Exception "SSL Handshake failed"

我正在将 android 应用程序移植到 javaFX 以进行 windows 部署,我是 javaFX 和桌面部署的新手,但对java.

该应用程序包含一个 WebView,它加载通过 Json 从服务器获取的 url(因此基本上可以是任何东西)。

openJDK 14、openJfx 16、intellij idea ultimate 2021.1.3,gradle:插件:org.beryx.jlink & org.openjfx.javafxplugin

当我 运行 开发和测试程序(在 windows 10 机器上)时,这工作正常,但是当它被打包并部署在 windows 机器上时(任何windows 10 到目前为止)我在加载页面时收到“java.lang.Throwable:SSL 握手失败”异常。

这是堆栈跟踪:

    [ERROR] 2021-07-14 14:13:53.737 [JavaFX Application Thread] MediaElementWeb - WebView Failed: 
java.lang.Throwable: SSL handshake failed
    at javafx.scene.web.WebEngine$LoadWorker.describeError(WebEngine.java:1440) ~[javafx.web:?]
    at javafx.scene.web.WebEngine$LoadWorker.dispatchLoadEvent(WebEngine.java:1379) ~[javafx.web:?]
    at javafx.scene.web.WebEngine$PageLoadListener.dispatchLoadEvent(WebEngine.java:1240) ~[javafx.web:?]
    at com.sun.webkit.WebPage.fireLoadEvent(WebPage.java:2524) ~[javafx.web:?]
    at com.sun.webkit.WebPage.fwkFireLoadEvent(WebPage.java:2369) ~[javafx.web:?]
    at com.sun.webkit.network.URLLoaderBase.twkDidFail(Native Method) ~[javafx.web:?]
    at com.sun.webkit.network.URLLoader.notifyDidFail(URLLoader.java:799) ~[javafx.web:?]
    at com.sun.webkit.network.URLLoader.lambda$didFail(URLLoader.java:782) ~[javafx.web:?]
    at com.sun.javafx.application.PlatformImpl.lambda$runLater(PlatformImpl.java:447) ~[javafx.graphics:?]
    at java.security.AccessController.doPrivileged(AccessController.java:391) ~[?:?]
    at com.sun.javafx.application.PlatformImpl.lambda$runLater(PlatformImpl.java:446) ~[javafx.graphics:?]
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96) ~[javafx.graphics:?]
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method) ~[javafx.graphics:?]
    at com.sun.glass.ui.win.WinApplication.lambda$runLoop(WinApplication.java:174) ~[javafx.graphics:?]
    at java.lang.Thread.run(Thread.java:832) [?:?]

该问题不特定于任何特定证书,所以我知道这不是一般证书的问题,已在许多网站上进行了测试。我只在部署的应用程序中收到此错误。

正在以标准方式加载页面:WebEngine.load(targetURL);

我正在捕获错误:

tNode.getEngine().getLoadWorker().stateProperty().addListener((o, ov, nv) -> {
            if (nv == Worker.State.FAILED) {
                logger.error("WebView Failed: ", tNode.getEngine().getLoadWorker().getException());
            }
        });

我已经搜索并尝试了其他人提供的解决方案,这些解决方案似乎遇到了类似的错误,例如:

在调用 load(page) 之前设置信任管理器:

TrustManager[] trustAllCerts = new TrustManager[] {
                new X509TrustManager() {
                    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                        return null;
                    }
                    public void checkClientTrusted(
                            java.security.cert.X509Certificate[] certs, String authType) {
                    }
                    public void checkServerTrusted(
                            java.security.cert.X509Certificate[] certs, String authType) {
                    }
                }
        };
        // Install the all-trusting trust manager
        try {
            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null, trustAllCerts, new java.security.SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
        } catch (GeneralSecurityException e) {
            logger.error("SSLContext Failed: ", e);
        }

(这里没有错误或影响)

在部署中设置 JVMarg

-Dcom.sun.webkit.useHTTP2Loader=false

我可以看到在堆栈跟踪中显示的效果是“com.sun.webkit.network.URLLoader”而不是 http2(正如在其他线程上所建议的那样),但这里也没有变化。

有没有人(记住我是 java 桌面部署的新手)有什么问题以及如何解决它?

非常感谢

更新:

Trace from console on deployed test https://pastebin.com/R5SkR4w1

前几行:

javax.net.ssl|WARNING|2C|URL-Loader-1|2021-07-15 10:46:45.991 BST|SignatureScheme.java:295|Signature algorithm, ed25519, is not supported by the underlying providers
javax.net.ssl|WARNING|2C|URL-Loader-1|2021-07-15 10:46:45.992 BST|SignatureScheme.java:295|Signature algorithm, ed448, is not supported by the underlying providers
javax.net.ssl|WARNING|2C|URL-Loader-1|2021-07-15 10:46:45.995 BST|NamedGroup.java:297|No AlgorithmParameters for x25519 (
"throwable" : {
  java.security.NoSuchAlgorithmException: Algorithm x25519 not available
        at java.base/javax.crypto.KeyAgreement.getInstance(KeyAgreement.java:192)
        at java.base/sun.security.ssl.NamedGroup.<init>(NamedGroup.java:286)
        at java.base/sun.security.ssl.NamedGroup.<clinit>(NamedGroup.java:184)
        at java.base/sun.security.ssl.SignatureScheme.<clinit>(SignatureScheme.java:59)
        at java.base/sun.security.ssl.SSLSessionImpl.<clinit>(SSLSessionImpl.java:823)
        at java.base/sun.security.ssl.TransportContext.<init>(TransportContext.java:133)
        at java.base/sun.security.ssl.TransportContext.<init>(TransportContext.java:103)
        at java.base/sun.security.ssl.SSLSocketImpl.<init>(SSLSocketImpl.java:111)
        at java.base/sun.security.ssl.SSLSocketFactoryImpl.createSocket(SSLSocketFactoryImpl.java:72)
        at java.base/sun.net.www.protocol.https.HttpsClient.createSocket(HttpsClient.java:413)
        at java.base/sun.net.NetworkClient.doConnect(NetworkClient.java:162)
        at java.base/sun.net.www.http.HttpClient.openServer(HttpClient.java:474)
        at java.base/sun.net.www.http.HttpClient.openServer(HttpClient.java:569)
        at java.base/sun.net.www.protocol.https.HttpsClient.<init>(HttpsClient.java:265)
        at java.base/sun.net.www.protocol.https.HttpsClient.New(HttpsClient.java:372)
        at ...

通过@slaw 关于我最初尝试但最终没有正确实施的建议的有用评论设法解决了这个问题,并从@dave_thompson_085 获得了如何提供额外调试信息的帮助。所以决议,和同船的人的一些提示:

1.解决方案:

Intellij IDEA 上 gradle 的 Badass Jlink 插件,Java 14 和 JavaFX 16 未正确合并安全提供程序 类。 这已通过将“jdk.crypto.ec”添加到合并模块列表来解决。

2。手动添加模块

org.beryx.jlink 插件 (2.24.0) 非常复杂和强大,所以我很难弄清楚如何用我的实现来实现它。

我尝试了很多组合,但下面的代码在我的build.gradle中为我做了:

jlink  {
    //... Other jlink \ jpackage stuff
    mergedModule {
        additive = true
        requires 'jdk.crypto.ec'
    }
    //... Other jlink \ jpackage stuff
}

3。为 windows

调试打包的 java 二进制文件

一些 Jlink 配置更改对整个过程有所帮助。

jlink  {
    //..
    jpackage {
        //..
        imageOptions = [
                "--win-console"
        ]
    }
    //..    
    launcher {
        jvmArgs = ['-Dcom.sun.webkit.useHTTP2Loader=false','-Djavax.net.debug=ssl:handshake']
    }

}

--win-console 当你启动你的程序时打开一个控制台window 这样你就可以看到注销放

-Djavax.net.debug=ssl:handshake 提供了有关 SSL 过程和握手的更多信息,因此您可以了解什么是正在发生。