0

I have developed a simple JavaFX app using jgit, that is allowing users to play with git.

When the app was started from the IntelliJ idea, I was able to clone the GitHub repo using my jgit implementation of the "git clone" command without any issues. But as soon as I created an image from my app and started the app from the image, I am getting an SSL certificate issue:

Exception:org.eclipse.jgit.api.errors.TransportException: Secure connection to https://my-github-repo.git could not be established because of SSL problems.

I am trying to understand why I am getting the SSL certificate issue only when I am running the app from the image. Can somebody explain that? I understand that I can disable SSL verification (there are some questions answered on that topic), but I want to know why it is working from IDE and not from the created image...

here is my simplified git clone implementation for http:

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);
}

For creating the image I am using the "org.beryx.runtime" plugin with the Gradle task "runtime".

Here is the build.gradle content:

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")
}

Edit 1:

How the image is created? - image is created with the plugin 'org.beryx.runtime' version '1.11.4', with Gradle task called 'runtime'. At the end of the build.gradle content you can see some specific configuration for runtime task.

Also, it is possible to include modules there as described here: https://badass-runtime-plugin.beryx.org/releases/latest/

I have tested the config with modules you are mentioning for runtime task in build.gradle (also one by one):

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']
}

But with that I am getting following exception when starting the app from image:

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

What version of Java 11 are you using? - java version "11.0.8" 2020-07-14 LTS Regarding the different versions of JDK for image and for IntelliJ IDEA environment - it should be using the same installation on my machine

I guess I need to add modules to the runtime task, but I do not know which ones and how to identify them... Any direction you can point me to?

Edit 2:

According to the accepted answer, I was missing modules in my runtime task configuration. Here is how I have figured which ones to add:

The plugin 'org.beryx.runtime' contains a task I used for suggesting modules for the runtime task (task: suggestModules) After running it I have created a list of modules with the following runtime config (included the ones from accepted answer):

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']
}

Now everything works as expected.

psova
  • 192
  • 2
  • 11
  • Please share any exceptions you are getting. – swpalmer Nov 11 '20 at 20:57
  • I have edited the question. Thank you for your time and effort. – psova Nov 11 '20 at 22:50
  • Add the whole stack trace for the exception. Eg. is there a "caused by" mentioned? – swpalmer Nov 12 '20 at 03:27
  • There is nothing more in the stacktrace just this: 2020-11-12 10:09:47,727 [ERROR] [Thread-5] taman.utils.GitUtils - Error occurred during task: Git clone: org.eclipse.jgit.api.errors.TransportException: https://github.com/my-repo.git: Secure connection to https://github.com/my-repo.git could not be established because of SSL problems – psova Nov 12 '20 at 09:11

1 Answers1

1

The most likely situation is that you are missing a module in the JRE image related to crypto that is required to authenticate the SSL connection.

What jdk.crypto.* modules are in the final image? Perhaps if one of these is missing it will affect the ability to handle the SSL certificates?

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

Since some aspects of the security/crypto code are done via service providers, perhaps when you generate the JRE image you should pass the "--bind-services" option to "Link in service provider modules and their dependences"

You will need to share more details about how the image is created and what specific errors are reported. Try to include the full stack trace of any reported exceptions.

What version of Java 11 are you using? Could you be running into this: JDK 11 SSL Error on valid certificate (working in previous versions)

(It is unlikely if you are running with the same JDK version in the IDE and the packaged image, but thought I would mention it just in case it gives you a hint.)

swpalmer
  • 3,890
  • 2
  • 23
  • 31
  • Hi @swpalmer, thank you for your answer, I have added the build.gradle content. Everything else was already there (exception and the way how the image is prepared...), I made it bold now that it is more visible. Regarding your answer, you are mentioning a module related to crypto. Can you elaborate a little bit more about that? Thank you for your time and effort. – psova Nov 11 '20 at 22:50
  • I have found a solution using your suggested modules. Thank you very much! – psova Nov 12 '20 at 10:00