javafx 16 WebEngine 异常“SSL 握手失败”

Tim*_*m W 4 ssl javafx jlink javafx-webengine java-14

我正在将 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$6(URLLoader.java:782) ~[javafx.web:?]
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:447) ~[javafx.graphics:?]
    at java.security.AccessController.doPrivileged(AccessController.java:391) ~[?:?]
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$11(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$3(WinApplication.java:174) ~[javafx.graphics:?]
    at java.lang.Thread.run(Thread.java:832) [?:?]
Run Code Online (Sandbox Code Playgroud)

该问题并不特定于任何特定证书,因此我知道这通常不是特定于证书的问题,经过许多站点的测试。我只在部署的应用程序中收到此错误。

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

我正在捕获错误:

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

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

在调用 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);
        }
Run Code Online (Sandbox Code Playgroud)

(这里没有错误或影响)

在部署上设置 JVMarg

-Dcom.sun.webkit.useHTTP2Loader=false
Run Code Online (Sandbox Code Playgroud)

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

有没有人对问题是什么以及如何解决它有任何想法(考虑到我是java桌面部署的新手)?

非常感谢

更新:

从控制台跟踪已部署的测试 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 ...
Run Code Online (Sandbox Code Playgroud)

Tim*_*m W 5

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

1、解决办法:

Intellij IDEA 上适用于 Java 14 和 JavaFX 16 的 Badass Jlink gradle 插件未正确合并安全提供程序类。通过将“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
}
Run Code Online (Sandbox Code Playgroud)

3. 调试 Windows 下打包的 java 二进制文件

一些 Jlink 配置更改一路上有所帮助。

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

}
Run Code Online (Sandbox Code Playgroud)

--win-console在启动程序时打开控制台窗口,以便您可以看到日志输出

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