Summary
For a JavaFX desktop app packaged with jDeploy, the launch splash screen (splash.png/splash.gif) is never dismissed once the app's main window is up and running:
- macOS: the splash stays on top of the app window, blocking interaction entirely — the app is effectively unusable until the user manually kills/hides the splash.
- Linux: the app window does come to the front and is usable, but the splash remains rendered underneath it (never actually closed/torn down).
This can be seen in release 1.2.0 of MelodyMatrix, available at https://github.com/codewriterbv/melodymatrix-app-releases/releases#release-1.2.0
Environment
- jDeploy
6.1.1 (via shannah/jdeploy@master GitHub Action)
- Java 25, JavaFX 26 (
-Djavafx.enablePreview=true --enable-native-access=javafx.graphics)
jdeploy config: "javafx": true, bundles for mac-x64, mac-arm64, win, linux
- Repro'd across multiple app releases (regressed between our own two releases roughly two weeks apart, same jDeploy default version — see below)
What we ruled out before filing
- Splash image itself — swapped an animated
splash.gif back to a plain static splash.png; identical behavior either way. Not image-format-related.
- jDeploy version drift — confirmed via our GitHub Actions run logs that both the last known-good release and the regressed one resolved
shannah/jdeploy@master using the same jdeploy_version: 6.1.1 default (per action.yml history, that default was set on 2026-03-15 and hadn't changed across either build date). So this isn't a case of @master picking up a different jDeploy release between builds.
- App-side
SplashScreen API usage — our app never calls java.awt.SplashScreen anywhere; we rely entirely on jDeploy's own splash handling via the splash.png/splash.gif filename convention.
- New blocking startup code — audited our app's JavaFX startup path (everything running on the FX Application Thread before/around
Stage.show()) against our last known-good release; no new blocking/synchronous call was introduced there.
- Shaded-jar service merging — we added a
ServicesResourceTransformer to our Maven Shade config around the same time and suspected it might be involved; inspected the merged META-INF/services/* entries in the built jar and they're all correct/clean (no duplicate or conflicting SPI providers).
- Workaround confirms isolation to the splash mechanism: removing
splash.png/splash.gif entirely (so jDeploy shows no launch splash at all) makes the app launch and behave normally on both platforms. This confirms the app itself starts and becomes ready correctly — the bug is specifically in how/whether jDeploy detects readiness and dismisses the splash for a JavaFX app.
Question for maintainers
Since JavaFX doesn't create an AWT window, it won't trigger whatever "close splash when a window appears" heuristic might work for Swing/AWT apps. How is splash dismissal supposed to work for JavaFX apps specifically — is it a window-enumeration poll, a fixed timeout, or does the app need to signal readiness explicitly (e.g. a marker on stdout, a file, an exit code)? Is this expected to be reliable/deterministic, or could it be a timing race that's more likely to lose on some machines than others (which would explain the mac vs. Linux difference we saw)?
Summary
For a JavaFX desktop app packaged with jDeploy, the launch splash screen (
splash.png/splash.gif) is never dismissed once the app's main window is up and running:This can be seen in release 1.2.0 of MelodyMatrix, available at https://github.com/codewriterbv/melodymatrix-app-releases/releases#release-1.2.0
Environment
6.1.1(viashannah/jdeploy@masterGitHub Action)-Djavafx.enablePreview=true --enable-native-access=javafx.graphics)jdeployconfig:"javafx": true, bundles formac-x64,mac-arm64,win,linuxWhat we ruled out before filing
splash.gifback to a plain staticsplash.png; identical behavior either way. Not image-format-related.shannah/jdeploy@masterusing the samejdeploy_version: 6.1.1default (peraction.ymlhistory, that default was set on 2026-03-15 and hadn't changed across either build date). So this isn't a case of@masterpicking up a different jDeploy release between builds.SplashScreenAPI usage — our app never callsjava.awt.SplashScreenanywhere; we rely entirely on jDeploy's own splash handling via thesplash.png/splash.giffilename convention.Stage.show()) against our last known-good release; no new blocking/synchronous call was introduced there.ServicesResourceTransformerto our Maven Shade config around the same time and suspected it might be involved; inspected the mergedMETA-INF/services/*entries in the built jar and they're all correct/clean (no duplicate or conflicting SPI providers).splash.png/splash.gifentirely (so jDeploy shows no launch splash at all) makes the app launch and behave normally on both platforms. This confirms the app itself starts and becomes ready correctly — the bug is specifically in how/whether jDeploy detects readiness and dismisses the splash for a JavaFX app.Question for maintainers
Since JavaFX doesn't create an AWT window, it won't trigger whatever "close splash when a window appears" heuristic might work for Swing/AWT apps. How is splash dismissal supposed to work for JavaFX apps specifically — is it a window-enumeration poll, a fixed timeout, or does the app need to signal readiness explicitly (e.g. a marker on stdout, a file, an exit code)? Is this expected to be reliable/deterministic, or could it be a timing race that's more likely to lose on some machines than others (which would explain the mac vs. Linux difference we saw)?