1

I try to get the latest release tag of a Github repositiory via HttpClient.
The plan is to send a request to github.com/user/repository/releases/latest and get the uri of the redirect to determine the latest release tag.

When the program is running in my IDE, everything works fine. But for some reasons a IOException is thrown when the program is jlinked + jpackaged.
I allready tried to run it as an admin to rule that out.

My code:

  private static String latestVersionTag() {
        HttpClient client = HttpClient.newBuilder().followRedirects(HttpClient.Redirect.NORMAL).build();
        HttpRequest request = HttpRequest
                .newBuilder(URI.create("https://github.com/{placeholderUser}/{placeholderRepo}/releases/latest"))
                .timeout(Duration.ofSeconds(5))
                .build();

        try {
            HttpResponse<InputStream> response = client.send(request, HttpResponse.BodyHandlers.ofInputStream());
            String path = response.uri().getPath();
            return path.substring(path.lastIndexOf('/') + 1);
        } catch (IOException | InterruptedException e) {
            return null;
        }
    }

Edit: i ran the jlinked image without packaging to get the stack trace (haven't thought of that before, sorry)

javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
        at java.net.http/jdk.internal.net.http.HttpClientImpl.send(HttpClientImpl.java:576)
        at java.net.http/jdk.internal.net.http.HttpClientFacade.send(HttpClientFacade.java:123)
        at launchofexile/com.github.cptblacksheep.launchofexile.UpdateChecker.latestVersionTag(UpdateChecker.java:76)
        at launchofexile/com.github.cptblacksheep.launchofexile.UpdateChecker.checkForNewVersion(UpdateChecker.java:35)
        at launchofexile/com.github.cptblacksheep.launchofexile.UpdateChecker.startupCheckForNewVersion(UpdateChecker.java:28)
        at launchofexile/com.github.cptblacksheep.launchofexile.LaunchOfExileMain.initialize(LaunchOfExileMain.java:285)
        at launchofexile/com.github.cptblacksheep.launchofexile.LaunchOfExileMain.main(LaunchOfExileMain.java:475)
Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
        at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131)
        at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:117)
        at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:358)
        at java.base/sun.security.ssl.Alert$AlertConsumer.consume(Alert.java:293)
        at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:204)
        at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:172)
        at java.base/sun.security.ssl.SSLEngineImpl.decode(SSLEngineImpl.java:736)
        at java.base/sun.security.ssl.SSLEngineImpl.readRecord(SSLEngineImpl.java:691)
        at java.base/sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:506)
        at java.base/sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:482)
        at java.base/javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:679)
        at java.net.http/jdk.internal.net.http.common.SSLFlowDelegate$Reader.unwrapBuffer(SSLFlowDelegate.java:529)
        at java.net.http/jdk.internal.net.http.common.SSLFlowDelegate$Reader.processData(SSLFlowDelegate.java:433)
        at java.net.http/jdk.internal.net.http.common.SSLFlowDelegate$Reader$ReaderDownstreamPusher.run(SSLFlowDelegate.java:268)
        at java.net.http/jdk.internal.net.http.common.SequentialScheduler$LockingRestartableTask.run(SequentialScheduler.java:205)
        at java.net.http/jdk.internal.net.http.common.SequentialScheduler$CompleteRestartableTask.run(SequentialScheduler.java:149)
        at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SchedulableTask.run(SequentialScheduler.java:230)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
        at java.base/java.lang.Thread.run(Thread.java:833)
  • What do you mean by this? `jlinked + jpackaged` – Mohamad Ghaith Alzin May 28 '22 at 12:48
  • By jlinked + jpackaged i mean that i used jlink to create a runtime image und jpackage to create an installer for the program – CptBlacksheep May 28 '22 at 12:57
  • 3
    @CptBlacksheep Welcome to Stack Overflow. Please take the [tour] to learn how Stack Overflow works and read [ask] on how to improve the quality of your question. Then [edit] your question to include your source code as a working [mcve], which can be compiled and tested by others. Also add the full complete exception message and stacktrace you get to your question. – Progman May 28 '22 at 13:06
  • so, to clarify, packing your java program using jlink and jpackage throws `IOException`? or is it at runtime after the packing? what the exception message says? – Bagus Tesa May 28 '22 at 13:43
  • If you print a stack trace where you catch the exception it may help. – ewramner May 28 '22 at 14:10
  • It's my program at runtime that throws the IOException when executing the given code piece. When i execute the same code piece in intellij it works without problems. I can't really provide a stack trace as it only happens outside the IDE. I tried to catch all possible exceptions that .send() can throw seperately (and showed a joptionpane with a corresponding error message) to find out it's the IOException that gets thrown. – CptBlacksheep May 28 '22 at 14:16
  • Which modules are included in the `jlink`-built image? I remember someone else once having a problem with missing cryptographic modules, causing handshakes (or something) to fail. – Slaw May 28 '22 at 14:31
  • @Slow You might be right, i use apaches maven jlink plugin to jlink, so it should theoretically include all relevant dependencies. But when i go after the legal folders in the image there's only java.base, java.datatransfer, java.desktop, java.net.http, java.prefs, java.xml. nothing cryptographic – CptBlacksheep May 28 '22 at 15:04
  • Try configuring the plugin to include `--add-modules jdk.crypto.cryptoki,jdk.crypto.ec`. – Slaw May 28 '22 at 15:05
  • Including jdk.crypto.cryptoki solved my problem. Thank you very much! – CptBlacksheep May 28 '22 at 15:09

1 Answers1

3

The handshake is failing because your custom run-time image is missing the necessary cryptography modules. Adding:

--add-modules jdk.crypto.cryptoki,jdk.crypto.ec

When running jlink should fix the problem.

I'm not sure if you absolutely need both modules, or which of the two is the necessary one if you don't need both. It's also possible one of them requires the other, causing the other to be implicitly pulled in.

Slaw
  • 37,820
  • 8
  • 53
  • 80