1

I have a user who has a license to use Swiss Topo maps and requires my application to pull these tiles down. In my main project I pull the tiles from the following type of URL https://wmts10.geo.admin.ch/1.0.0/ch.swisstopo.pixelkarte-farbe/default/current/3857/11/1074/[tile id].jpeg. When I initially implemented this in my main project, which I compile as a non-modular image against OpenJDK11.0, there was an issue because of a known bug with TLSv1.3 pre openJDK11.02. The work around was to use the JVM param -Dhttps.protocols=TLSv1.2 to force my application to use TLSv1.2. This worked within my IDE but when I made the image using Beryx Badass Runtime it's as if the JVM param is ignored, I do see that Beryx has added it to the batch file that launches the image though. I then decided I would try against OpenJDK 11.02 as this was meant to have a fix for TLSv1.3 and doesn't require that I force the TLS version to 1.2 with the JVM param. Again, this works when running from within my IDE (without a JVM param) but when I use Beryx to create the runtime image I see the same SSLExceptions. If I build the runtime with the following JVM param -Djavax.net.debug=ssl:handshake I see the following (it looks like OpenJDK11.02 only tries TLSv1.2?):

Reprex.bat
WARNING: Unknown module: javafx.graphics specified to --add-exports
WARNING: Unknown module: javafx.controls specified to --add-exports
WARNING: Unknown module: javafx.controls specified to --add-exports
WARNING: Unknown module: javafx.graphics specified to --add-exports
WARNING: package javax.naming not in java.base
WARNING: Unknown module: javafx.controls specified to --add-exports
WARNING: Unknown module: javafx.base specified to --add-exports
WARNING: Unknown module: javafx.graphics specified to --add-exports
WARNING: Unknown module: javafx.graphics specified to --add-exports
WARNING: Unknown module: javafx.controls specified to --add-exports
WARNING: Unknown module: javafx.base specified to --add-exports
WARNING: Unknown module: javafx.controls specified to --add-exports
WARNING: Unknown module: javafx.graphics specified to --add-exports
WARNING: Unknown module: javafx.controls specified to --add-opens
WARNING: Unknown module: javafx.graphics specified to --add-opens
https://wmts10.geo.admin.ch/1.0.0/ch.swisstopo.pixelkarte-farbe/default/current/3857/11/1074/715.jpeg
javax.net.ssl|DEBUG|1B|Thread-3|2022-11-30 13:10:17.146 GMT|null:-1|jdk.tls.keyLimits:  entry = AES/GCM/NoPadding KeyUpdate 2^37. AES/GCM/NOPADDING:KEYUPDATE = 137438953472
javax.net.ssl|DEBUG|1B|Thread-3|2022-11-30 13:10:17.571 GMT|null:-1|the previous server name in SNI (type=host_name (0), value=wmts10.geo.admin.ch) was replaced with (type=host_name (0), value=wmts10.geo.admin.ch)
javax.net.ssl|WARNING|1B|Thread-3|2022-11-30 13:10:17.586 GMT|null:-1|Signature algorithm, ed25519, is not supported by the underlying providers
javax.net.ssl|WARNING|1B|Thread-3|2022-11-30 13:10:17.587 GMT|null:-1|Signature algorithm, ed448, is not supported by the underlying providers
javax.net.ssl|WARNING|1B|Thread-3|2022-11-30 13:10:17.587 GMT|null:-1|Signature algorithm, SHA256withECDSA, is not supported by the underlying providers
javax.net.ssl|WARNING|1B|Thread-3|2022-11-30 13:10:17.587 GMT|null:-1|Signature algorithm, SHA384withECDSA, is not supported by the underlying providers
javax.net.ssl|WARNING|1B|Thread-3|2022-11-30 13:10:17.587 GMT|null:-1|Signature algorithm, SHA512withECDSA, is not supported by the underlying providers
javax.net.ssl|WARNING|1B|Thread-3|2022-11-30 13:10:17.589 GMT|null:-1|Signature algorithm, SHA224withECDSA, is not supported by the underlying providers
javax.net.ssl|WARNING|1B|Thread-3|2022-11-30 13:10:17.590 GMT|null:-1|Signature algorithm, SHA1withECDSA, is not supported by the underlying providers
javax.net.ssl|INFO|1B|Thread-3|2022-11-30 13:10:17.591 GMT|null:-1|No available application protocols
javax.net.ssl|DEBUG|1B|Thread-3|2022-11-30 13:10:17.592 GMT|null:-1|Ignore, context unavailable extension: application_layer_protocol_negotiation
javax.net.ssl|DEBUG|1B|Thread-3|2022-11-30 13:10:17.593 GMT|null:-1|Ignore, context unavailable extension: cookie
javax.net.ssl|DEBUG|1B|Thread-3|2022-11-30 13:10:17.622 GMT|null:-1|No session to resume.
javax.net.ssl|DEBUG|1B|Thread-3|2022-11-30 13:10:17.622 GMT|null:-1|Ignore, context unavailable extension: pre_shared_key
javax.net.ssl|DEBUG|1B|Thread-3|2022-11-30 13:10:17.623 GMT|null:-1|Produced ClientHello handshake message (
"ClientHello": {
  "client version"      : "TLSv1.2",
  "random"              : "31 5F 56 DC E8 EC 9D 92 1B C6 63 D0 F2 B7 62 83 18 E9 3E 13 6D D2 6D 0E 5E 63 39 7D 18 58 66 0E",
  "session id"          : "A3 84 68 4B EB 32 A8 27 22 62 73 44 42 03 76 CE 7C E4 A9 88 FC D1 E6 98 9D 70 BF D6 E0 D5 5F 20",
  "cipher suites"       : "[TLS_AES_128_GCM_SHA256(0x1301), TLS_AES_256_GCM_SHA384(0x1302), TLS_RSA_WITH_AES_256_GCM_SHA384(0x009D), TLS_DHE_RSA_WITH_AES_256_GCM_SHA384(0x009F), TLS_DHE_DSS_WITH_AES_256_GCM_SHA384(0x00A3), TLS_RSA_WITH_AES_128_GCM_SHA256(0x009C), TLS_DHE_RSA_WITH_AES_128_GCM_SHA256(0x009E), TLS_DHE_DSS_WITH_AES_128_GCM_SHA256(0x00A2), TLS_RSA_WITH_AES_256_CBC_SHA256(0x003D), TLS_DHE_RSA_WITH_AES_256_CBC_SHA256(0x006B), TLS_DHE_DSS_WITH_AES_256_CBC_SHA256(0x006A), TLS_RSA_WITH_AES_256_CBC_SHA(0x0035), TLS_DHE_RSA_WITH_AES_256_CBC_SHA(0x0039), TLS_DHE_DSS_WITH_AES_256_CBC_SHA(0x0038), TLS_RSA_WITH_AES_128_CBC_SHA256(0x003C), TLS_DHE_RSA_WITH_AES_128_CBC_SHA256(0x0067), TLS_DHE_DSS_WITH_AES_128_CBC_SHA256(0x0040), TLS_RSA_WITH_AES_128_CBC_SHA(0x002F), TLS_DHE_RSA_WITH_AES_128_CBC_SHA(0x0033), TLS_DHE_DSS_WITH_AES_128_CBC_SHA(0x0032)]",
  "compression methods" : "00",
  "extensions"          : [

  ]
}
)
javax.net.ssl|DEBUG|1B|Thread-3|2022-11-30 13:10:40.229 GMT|null:-1|Received alert message (
"Alert": {
  "level"      : "warning",
  "description": "close_notify"
}
)
javax.net.ssl|ERROR|1B|Thread-3|2022-11-30 13:10:40.230 GMT|null:-1|Fatal (UNEXPECTED_MESSAGE): Received close_notify during handshake (
"throwable" : {
  javax.net.ssl.SSLProtocolException: Received close_notify during handshake
        at java.base/sun.security.ssl.Alert.createSSLException(Unknown Source)
        at java.base/sun.security.ssl.Alert.createSSLException(Unknown Source)
        at java.base/sun.security.ssl.TransportContext.fatal(Unknown Source)
        at java.base/sun.security.ssl.TransportContext.fatal(Unknown Source)
        at java.base/sun.security.ssl.TransportContext.fatal(Unknown Source)
        at java.base/sun.security.ssl.Alert$AlertConsumer.consume(Unknown Source)
        at java.base/sun.security.ssl.TransportContext.dispatch(Unknown Source)
        at java.base/sun.security.ssl.SSLTransport.decode(Unknown Source)
        at java.base/sun.security.ssl.SSLSocketImpl.decode(Unknown Source)
        at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(Unknown Source)
        at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
        at java.base/sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
        at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
        at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(Unknown Source)
        at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
        at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(Unknown Source)
        at sample.Main$1.call(Main.java:60)
        at javafx.concurrent.Task$TaskCallable.call(Task.java:1425)
        at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
        at java.base/java.lang.Thread.run(Unknown Source)}

)
javax.net.ssl|DEBUG|1B|Thread-3|2022-11-30 13:10:40.231 GMT|null:-1|close the underlying socket
javax.net.ssl|DEBUG|1B|Thread-3|2022-11-30 13:10:40.232 GMT|null:-1|close the SSL connection (passive)
javax.net.ssl.SSLProtocolException: Received close_notify during handshake
        at java.base/sun.security.ssl.Alert.createSSLException(Unknown Source)
        at java.base/sun.security.ssl.Alert.createSSLException(Unknown Source)
        at java.base/sun.security.ssl.TransportContext.fatal(Unknown Source)
        at java.base/sun.security.ssl.TransportContext.fatal(Unknown Source)
        at java.base/sun.security.ssl.TransportContext.fatal(Unknown Source)
        at java.base/sun.security.ssl.Alert$AlertConsumer.consume(Unknown Source)
        at java.base/sun.security.ssl.TransportContext.dispatch(Unknown Source)
        at java.base/sun.security.ssl.SSLTransport.decode(Unknown Source)
        at java.base/sun.security.ssl.SSLSocketImpl.decode(Unknown Source)
        at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(Unknown Source)
        at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
        at java.base/sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
        at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
        at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(Unknown Source)
        at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
        at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(Unknown Source)
        at sample.Main$1.call(Main.java:60)
        at javafx.concurrent.Task$TaskCallable.call(Task.java:1425)
        at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
        at java.base/java.lang.Thread.run(Unknown Source)

You will also notice a number of WARNING: Unknown module: messages at the start of that output but I'll address those later.

I have created a reprex project which can be found at https://github.com/chrisrush1/MVPDoExportsTLSReprex I've included some commented out jvm params in the build.gradle which I've been using to see more detail on the SSL exception and to force the TLS version. Within the Main.java there is some code I've commented out that will force the TLS version in code, I tried this to see if the Beryx runtime was failing to pass the JVM param but that isn't the issue. Something different happens with the SSL request when running the image Beryx runtime creates than when the application is just run within the IDE and I'm struggling to see what that is. Within the runtime block in my build.gradle I do the follow just to make sure it is using the correct OpenJDK which I set using the Env var JAVA_HOME, I don't think it should be necessary though.

runtime {
    javaHome.set(System.getenv('JAVA_HOME'))
    println "runtime JavaHome path:${javaHome.get()}"
    options = ['--strip-debug', '--compress', '2', '--no-header-files', '--no-man-pages']
}

In addition to the above issue you can see the WARNING messages about 'unknown module'. I've included all the add-exports and add-opens commands required by my main project in the build.gradle for this reprex project so that all these WARNINGS can be seen. These warnings are odd because they would imply the modules are missing but the main application runs correctly and wouldn't if I removed the add-exports/add-opens so I'm not sure why when launching the image from the bat file created these are displayed? javafx.graphics and javafx.controls are vital to my main project so they must be in the image as it launches and runs without issue so why the warnings?

The modules file created for my image with badass runtime contains the following

bin\java --list-modules
java.base@11.0.2
java.compiler@11.0.2
java.datatransfer@11.0.2
java.desktop@11.0.2
java.instrument@11.0.2
java.logging@11.0.2
java.management@11.0.2
java.management.rmi@11.0.2
java.naming@11.0.2
java.net.http@11.0.2
java.prefs@11.0.2
java.rmi@11.0.2
java.scripting@11.0.2
java.se@11.0.2
java.security.jgss@11.0.2
java.security.sasl@11.0.2
java.smartcardio@11.0.2
java.sql@11.0.2
java.sql.rowset@11.0.2
java.transaction.xa@11.0.2
java.xml@11.0.2
java.xml.crypto@11.0.2
jdk.accessibility@11.0.2
jdk.aot@11.0.2
jdk.attach@11.0.2
jdk.charsets@11.0.2
jdk.compiler@11.0.2
jdk.crypto.cryptoki@11.0.2
jdk.crypto.ec@11.0.2
jdk.crypto.mscapi@11.0.2
jdk.dynalink@11.0.2
jdk.editpad@11.0.2
jdk.hotspot.agent@11.0.2
jdk.httpserver@11.0.2
jdk.internal.ed@11.0.2
jdk.internal.jvmstat@11.0.2
jdk.internal.le@11.0.2
jdk.internal.opt@11.0.2
jdk.internal.vm.ci@11.0.2
jdk.internal.vm.compiler@11.0.2
jdk.internal.vm.compiler.management@11.0.2
jdk.jartool@11.0.2
jdk.javadoc@11.0.2
jdk.jcmd@11.0.2
jdk.jconsole@11.0.2
jdk.jdeps@11.0.2
jdk.jdi@11.0.2
jdk.jdwp.agent@11.0.2
jdk.jfr@11.0.2
jdk.jlink@11.0.2
jdk.jshell@11.0.2
jdk.jsobject@11.0.2
jdk.jstatd@11.0.2
jdk.localedata@11.0.2
jdk.management@11.0.2
jdk.management.agent@11.0.2
jdk.management.jfr@11.0.2
jdk.naming.dns@11.0.2
jdk.naming.rmi@11.0.2
jdk.net@11.0.2
jdk.pack@11.0.2
jdk.rmic@11.0.2
jdk.scripting.nashorn@11.0.2
jdk.scripting.nashorn.shell@11.0.2
jdk.sctp@11.0.2
jdk.security.auth@11.0.2
jdk.security.jgss@11.0.2
jdk.unsupported@11.0.2
jdk.unsupported.desktop@11.0.2
jdk.xml.dom@11.0.2
jdk.zipfs@11.0.2

My uderstanding was that the runtime plugin puts the javafx dependencies in the jar file under /lib along with my project classes, I see a lot of them in there including packages that are in javafx.base, javafx.controls and javafx.graphics, is this not where my image is using them from? Thanks

Thanks for any help with these issues.

rickybobby
  • 139
  • 10
  • The 'unknown module' stuff is probably different. JavaFX can (if you go through some hoops) be made to run from the classpath rather than the modulepath (though it is not supported or advised). Recent versions of JavaFX will warn if it detects this occurs, but still allow it. I don't know if that is what is occurring in your setup, nor whether the javafx modules are part of the modular image as you suspect. Running `bin/java --list-modules` in the root directory of the jlink output will tell you what modules are in the jlinked image. – jewelsea Dec 01 '22 at 08:49
  • 1
    *“I pull the tiles from the following type of URL”* -> provide the code for this, hopefully as a [mcve]. – jewelsea Dec 01 '22 at 08:55
  • Thanks for all the suggestions @jewelsea, I'll take a look at them tomorrow. I did create a reprex and including a link https://github.com/chrisrush1/MVPDoExportsTLSReprex hopefully you can pull that? – rickybobby Dec 01 '22 at 22:26
  • Yes, but it is best to edit the question and to put the code in the question rather than external github, it is just small and focused, so will fit fine. – jewelsea Dec 01 '22 at 22:32
  • Fair enough, I thought it might be easier to just pull the project as the badass runtime plugin needs a Launcher class as well. I can see you've already copied the pertinent part of my code into this thread, thank you. – rickybobby Dec 02 '22 at 10:37
  • I've edited my question above with the list of modules and more info about the contents of the /lib/ application jar file that I understood contained the javafx dependencies. – rickybobby Dec 02 '22 at 11:13
  • See: [Why did Java 9 introduce the JMOD file format?](https://stackoverflow.com/questions/44732915/why-did-java-9-introduce-the-jmod-file-format) the section on the jimage format (which is neither a jar nor a jmod) -> "When building a custom JRE image with the CLI tool jlink, all relevant (explicit or transistive) module dependencies' classes and resources (from JAR modules or JMODs) are compiled into a single optimized JIMAGE file (again, stored under /lib/modules)." I assume that the badass plugin does this behind the scenes (but I did not check). – jewelsea Dec 02 '22 at 11:29
  • I don't know why your module list for the image is so long. In my answer, there were only a few java and jdk modules needed. The javafx modules and my app module are included as well. Perhaps you are listing the modules of the jdk installation itself rather than the image you created. I ran the java command located in the target directory output by the jlink command invoked by the maven javafx plugin, so it only listed modules included in the custom image generated by jlink. But perhaps the badass plugin works differently by placing jars on the module path instead of in an image. – jewelsea Dec 02 '22 at 11:55
  • The module list question is quite different from the ssl handshake question, you can always ask such questions separately to get better responses. – jewelsea Dec 02 '22 at 12:01

1 Answers1

1

This issue is NOT related to JavaFX specifically, it will manifest in any Java program packaged as modular jlinked images that use SSL.

In order for SSL to work in a modular Java image, you need to include the following module in the image:

 jdk.crypto.cryptoki

Without this module, the jlinked image will hang trying to get an SSL socket, and eventually (after about 30 seconds) fail with the error:

javax.net.ssl.SSLProtocolException: Received close_notify during handshake
   // at SSL related stack trace...

This will occur because jlink won't, by default, bind in the sun security provider for public key cryptography that is required to support SSL connections.

From the cryptoki documentation:

Provides the implementation of the SunPKCS11 security provider.

You need some kind of public key security provider for SSL to function, either the standard one from the JDK or a 3rd party one like Bouncy Castle. Without it, the rest of the app will work, but some cryptography will not. The lookup and usage of security algorithms is a runtime thing, so everything will work until you try to use it (e.g. when you try to open an SSL connection).

To fix it, you can create a modular app that requires the necessary module in the module-info.java file with this line:

requires jdk.crypto.cryptoki;

Demonstration

I am going to give a Maven-based answer as I am more familiar with that toolset. I don't know Gradle well enough to advise on how to translate this answer for Gradle. For testing, I used OpenJDK 19.0.1 and JavaFX 19 on OS X (Intel) 13.0.1.

This example is derived from code by rickybobby.

To build the linked app:

mvn javafx:jlink

To run the linked app:

./target/app/bin/app

src/main/java/sample/Main.java

package sample;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;

import java.io.InputStream;
import java.net.URL;

public class Main extends Application {
    private static final String BASE_URL = "https://wmts10.geo.admin.ch/1.0.0/ch.swisstopo.pixelkarte-farbe/default/current/3857/11/1074/";
    private ImageView iv;

    @Override
    public void start(Stage primaryStage) throws Exception {
        HBox hBox = new HBox(0.0);
        hBox.setPrefHeight(400);
        hBox.setPrefWidth(600);
        iv = new ImageView();
        iv.setFitWidth(200);
        iv.setFitHeight(150);
        iv.setPreserveRatio(true);
        hBox.getChildren().add(iv);

        primaryStage.setScene(new Scene(hBox, 300, 275));
        primaryStage.show();

        //load map tile from server
        Task<Void> mapTileLoadTask = new Task<>() {
            @Override
            protected Void call() throws Exception {
                Thread.sleep(1000);

                Image image = null;
                for (int i = 715; i < 739; i++) {
                    String urlString = BASE_URL + i + ".jpeg";
                    System.out.println(urlString);
                    URL url = new URL(urlString);
                    try {
                        //open inputStream to show SSLHandshakeExpception seen in main project
                        InputStream inputStream = url.openConnection().getInputStream();

                        image = new Image(urlString, true);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    if (image != null)
                        setMapImage(image);
                    Thread.sleep(10);
                }

                return null;
            }
        };
        new Thread(mapTileLoadTask).start();
    }

    public synchronized void setMapImage(Image image) {
        Platform.runLater(() -> {
            if (iv != null)
                iv.setImage(image);
        });
    }

    public static void main(String[] args) {
        launch(args);
    }
}

src/main/java/module-info.java

module com.example.maptilemaven {
    requires javafx.controls;

    // if you comment out this line, SSL handshakes will fail in jlinked images.
    requires jdk.crypto.cryptoki;

    exports sample;
}

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>maptilemaven</artifactId>
    <version>1.0-SNAPSHOT</version>
    <name>maptilemaven</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>19</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.10.1</version>
                <configuration>
                    <source>19</source>
                    <target>19</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.openjfx</groupId>
                <artifactId>javafx-maven-plugin</artifactId>
                <version>0.0.8</version>
                <executions>
                    <execution>
                        <!-- Default configuration for running with: mvn clean javafx:run -->
                        <id>default-cli</id>
                        <configuration>
                            <mainClass>com.example.maptilemaven/sample.Main</mainClass>
                            <launcher>app</launcher>
                            <jlinkZipName>app</jlinkZipName>
                            <jlinkImageName>app</jlinkImageName>
                            <noManPages>true</noManPages>
                            <stripDebug>true</stripDebug>
                            <noHeaderFiles>true</noHeaderFiles>
                            
                            <!-- Normally the javafx maven plugin will find jlink in JAVA_HOME, but if you want to specify which version to use, set that here:
                            <jlinkExecutable>/Users/username/Library/Java/JavaVirtualMachines/openjdk-19.0.1/Contents/Home/bin/jlink</jlinkExecutable> 
                            -->
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

Verify of linked modules with this command:

.target/app/bin/java --list-modules

Outputs:

com.example.maptilemaven
java.base@19.0.1
java.datatransfer@19.0.1
java.desktop@19.0.1
java.prefs@19.0.1
java.xml@19.0.1
javafx.base@19
javafx.controls@19
javafx.graphics@19
jdk.crypto.cryptoki@19.0.1
jdk.crypto.ec@19.0.1
jdk.unsupported@19.0.1
jewelsea
  • 150,031
  • 14
  • 366
  • 406
  • 1
    Thank you for this in depth answer @jewelsea, this was indeed the issue and was therefore was not to do with BadAss Runtime plugin. Adding jdk.crypto.cryptoki; to the modules array in the badass runtime task fixed the issue. – rickybobby Dec 02 '22 at 10:33