javafx 应用程序映像中 jgit 与 javafx 应用程序运行时的 ssl 证书问题

ssl certificate issue for jgit in javafx app image versus javafx app runtime

我使用 jgit 开发了一个简单的 JavaFX 应用程序,允许用户使用 git.

当应用程序从 IntelliJ idea 启动时,我能够使用我的 jgit 实现“git 克隆”命令克隆 GitHub 存储库,没有任何问题.但是,一旦我从我的应用程序创建了一个图像并从该图像启动了该应用程序,我就遇到了 SSL 证书问题:

异常:org.eclipse.jgit.api.errors.TransportException: 由于 SSL 问题,无法建立与 https://my-github-repo.git 的安全连接。

我想了解为什么我只有在 运行 图片中的应用程序时才会收到 SSL 证书问题。有人可以解释一下吗? 我知道我可以禁用 SSL 验证(关于该主题回答了一些问题),但我想知道为什么它在 IDE 而不是创建的图像中工作...

这是我为 http:

简化的 git 克隆实现
try { 

            CloneCommand command = Git.cloneRepository();

            command.setCredentialsProvider(new UsernamePasswordCredentialsProvider(httpUsername, httpPassword));

            // run the clone command
            command.setURI(repositoryUrl);
            command.setDirectory(dirFramework);
            git = command.call();

} catch (Exception e) {
    LOG.error("Error occurred during task: Git clone: " + e);
}

为了创建图像,我使用了带有 Gradle 任务“运行时”的“org.beryx.runtime”插件。

这里是build.gradle内容:

plugins {
    id 'java'
    id 'application'
    id 'org.openjfx.javafxplugin' version '0.0.8'
    id 'org.beryx.runtime' version '1.11.4'
}

group 'org.sovap'
version '1.0-SNAPSHOT'

sourceCompatibility = 11
targetCompatibility = 11

repositories {
    mavenCentral()
}

dependencies {

    // xml stuff
    compile 'jakarta.xml.bind:jakarta.xml.bind-api:2.3.3'
    compile 'org.glassfish.jaxb:jaxb-runtime:2.3.2'
    compile 'jakarta.activation:jakarta.activation-api:1.2.2'

    // logger
    compile 'org.apache.logging.log4j:log4j-core:2.13.3'
    compile 'org.slf4j:slf4j-api:1.7.30'
    compile 'org.slf4j:slf4j-simple:1.7.30'

    // cucumber
    compile 'io.cucumber:gherkin:15.0.2'

    // jgit
    compile 'org.eclipse.jgit:org.eclipse.jgit:5.9.0.202009080501-r'
    compile 'org.eclipse.jgit:org.eclipse.jgit.archive:5.9.0.202009080501-r'
    compile 'org.eclipse.jgit:org.eclipse.jgit.ssh.jsch:5.9.0.202009080501-r'

    // file utils
    compile 'commons-io:commons-io:2.7'

    //controlsfx
    compile 'org.controlsfx:controlsfx:11.0.2'

}

javafx {
    version = "15"
    modules = ['javafx.controls', 'javafx.fxml', 'javafx.web', "javafx.graphics"]
}

application {
    mainClassName = 'org.sovap.taman.Launcher'
    applicationName = 'taman'
}

runtime {
    options = ['--strip-debug', '--compress', '2', '--no-header-files', '--no-man-pages']
    imageDir = file("$buildDir/taman")
}

编辑 1:

图像是如何创建的? - 图像是使用插件 'org.beryx.runtime' 版本 '1.11.4' 创建的,Gradle 任务名为 'runtime'。在build.gradle内容的最后你可以看到运行时任务的一些具体配置。

此外,可以按照此处所述在其中包含模块:https://badass-runtime-plugin.beryx.org/releases/latest/

我已经用你在build.gradle中提到的用于运行时任务的模块测试了配置(也是一个接一个):

runtime {
    options = ['--strip-debug', '--compress', '2', '--no-header-files', '--no-man-pages']
    imageDir = file("$buildDir/taman")
    modules = ['jdk.crypto.cryptoki', 'jdk.crypto.ec', 'jdk.crypto.mscapi']
}

但是从图像启动应用程序时出现以下异常:

Exception in thread "main" java.lang.NoClassDefFoundError: javax/xml/stream/XMLStreamException
        at org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilderFactory.newConfigurationBuilder(ConfigurationBuilderFactory.java:38)
        at org.apache.logging.log4j.core.config.properties.PropertiesConfigurationBuilder.<init>(PropertiesConfigurationBuilder.java:72)
        at org.apache.logging.log4j.core.config.properties.PropertiesConfigurationFactory.getConfiguration(PropertiesConfigurationFactory.java:52)
        at org.apache.logging.log4j.core.config.properties.PropertiesConfigurationFactory.getConfiguration(PropertiesConfigurationFactory.java:35)
        at org.apache.logging.log4j.core.config.ConfigurationFactory$Factory.getConfiguration(ConfigurationFactory.java:551)
        at org.apache.logging.log4j.core.config.ConfigurationFactory$Factory.getConfiguration(ConfigurationFactory.java:475)
        at org.apache.logging.log4j.core.config.ConfigurationFactory.getConfiguration(ConfigurationFactory.java:323)
        at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:687)
        at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:708)
        at org.apache.logging.log4j.core.LoggerContext.start(LoggerContext.java:263)
        at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:153)
        at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:45)
        at org.apache.logging.log4j.LogManager.getContext(LogManager.java:194)
        at org.apache.logging.log4j.LogManager.getLogger(LogManager.java:602)
        at org.sovap.taman.App.<clinit>(App.java:15)
        at org.sovap.taman.Launcher.main(Launcher.java:6)
Caused by: java.lang.ClassNotFoundException: javax.xml.stream.XMLStreamException
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(Unknown Source)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(Unknown Source)
        at java.base/java.lang.ClassLoader.loadClass(Unknown Source)
        ... 16 more

您使用的 Java 11 是什么版本? - java 版本“11.0.8” 2020-07-14 LTS 关于图像和 IntelliJ 的不同版本 JDK IDEA 环境 - 它应该在我的机器上使用相同的安装

我想我需要将模块添加到运行时任务中,但我不知道哪些模块以及如何识别它们...您能指出什么方向吗?

编辑 2:

根据接受的答案,我的运行时任务配置中缺少模块。以下是我如何确定要添加的内容:

插件'org.beryx.runtime'包含一个任务,我用于为运行时任务建议模块(任务:suggestModules) 在 运行 之后,我创建了一个模块列表,其中包含以下运行时配置(包括接受的答案中的配置):

runtime {
    options = ['--strip-debug', '--compress', '2', '--no-header-files', '--no-man-pages']
    imageDir = file("$buildDir/taman")
    modules = [
            'java.desktop',
            'java.logging',
            'java.xml',
            'java.compiler',
            'java.datatransfer',
            'java.rmi',
            'java.sql',
            'java.naming',
            'java.scripting',
            'java.management',
            'java.security.jgss',
            'jdk.jfr',
            'java.net.http',
            'jdk.jsobject',
            'jdk.xml.dom',
            'jdk.unsupported',
            'jdk.crypto.cryptoki',
            'jdk.crypto.ec',
            'jdk.crypto.mscapi']
}

现在一切正常。

最有可能的情况是您在 JRE 映像中缺少一个与加密相关的模块,该模块需要验证 SSL 连接。

最终图像中有哪些 jdk.crypto.* 模块? 也许如果其中之一丢失会影响处理 SSL 证书的能力?

  • jdk.crypto.cryptoki
  • jdk.crypto.ec
  • jdk.crypto.mscapi

由于 security/crypto 代码的某些方面是通过服务提供商完成的,也许当您生成 JRE 映像时,您应该通过 “--bind-services”选项“Link 在服务提供商模块及其依赖项中”

您将需要分享有关图像创建方式和报告的具体错误的更多详细信息。尝试包括任何报告的异常的完整堆栈跟踪。

您使用的 Java 11 是什么版本? 你能运行加入这个吗:

(如果您 运行 与 IDE 和打包图像中的 JDK 版本相同,则不太可能,但我想我会提到它以防它给您一个提示。)