Tracking: #391
The fat jar shades JavaFX into a single multi-platform jar. This breaks on non-x64 Linux, arm64 macOS, and any combination not covered by the bundled natives. It also conflates "library", "CLI runner", and "GUI app" into one artifact that is too big and too brittle.
3.1 replaces the fat jar with per-platform distributions produced by jpackage
plus two cross-platform ZIPs that locate the right JavaFX natives at runtime
(or skip JFX entirely).
| Artifact | Format | Bundled JRE | Bundled JFX | Audience |
|---|---|---|---|---|
| Windows x64 | MSI (signed) | yes | yes (in JDK) | Windows desktop users |
| Windows x64 | ZIP | yes | yes (in JDK) | Portable / no-install |
| Linux x64 | DEB + RPM | yes | yes (in JDK) | apt/dnf users |
| Linux x64 | ZIP | yes | yes (in JDK) | Portable |
| Linux aarch64 | DEB + RPM | yes | yes (in JDK) | ARM servers / SBCs |
| Linux aarch64 | ZIP | yes | yes (in JDK) | Portable ARM |
| Linux (any) | Flatpak | no (ext.) | bundled from full ZIP | Flathub |
| macOS aarch64 | DMG | yes | yes (in JDK) | Apple Silicon |
| macOS aarch64 | ZIP | yes | yes (in JDK) | Portable |
| full ZIP (cross-platform) | ZIP | no | all platforms inside | BYO-JRE, any OS |
| minimal ZIP (cross-plat.) | ZIP | no | none (Swing fallback) | CLI / packagers |
| SHA-256 checksums | .txt | — | — | Verification |
The current fat jar (-jar-with-dependencies) is dropped. The unshaded library
jar published to Maven Central is unaffected.
Dropped. jpackage MSI provides the same double-click UX plus enterprise
deployability. SignPath signing already targets MSI.
Deferred. DMGs in 3.1 are unsigned; users will see Gatekeeper warnings. A follow-up task adds Developer ID signing + notarization once the certificate is in place.
MSI is signed via SignPath.io (already wired in the current pipeline; reuse as-is).
Azul Zulu+FX 21 for jpackage runs (JavaFX is part of the JDK). This
eliminates a separate --module-path for JFX during packaging and gives the
native packages a single, self-consistent runtime.
For ZIP-launcher consumers (BYO-JRE), supported runtime is Java 21+ (any distribution). JFX is provided by the ZIP itself (full) or not required (minimal, Swing fallback).
- Contents: application jars + dependencies (no JFX, no JRE) + launchers.
- Behavior: launches in CLI mode; if a GUI is requested, the existing Swing
fallback (commit
e968978) takes over. No JavaFX is loaded. - Use cases: server-side signing, packagers (Debian, Homebrew formula authors), users who already maintain their own JDK+JFX.
- Contents: minimal ZIP + JavaFX jars for all supported platforms, named
with Maven classifiers (
javafx-graphics-21-linux.jar,javafx-graphics-21-linux-aarch64.jar,javafx-graphics-21-mac.jar,javafx-graphics-21-mac-aarch64.jar,javafx-graphics-21-win.jar, etc.). - Behavior at launch: a small bootstrap class (
com.intoolswetrust.jsignpdf.Bootstrap) performs (1) a Java version check, (2) readsos.name+os.archand picks the matching JFX classifier set, (3) assembles aURLClassLoader, (4) reflectively invokes the real main. If a classifier set is missing or fails to load, falls through to the Swing fallback. - Use cases: cross-platform USB stick, "one download works everywhere", CI environments.
The bootstrap lives in a separate Maven module (jsignpdf-bootstrap)
compiled with <maven.compiler.release>8</maven.compiler.release>. This is
deliberate: the rest of the project targets Java 21, but a class file at
bytecode level 65 (Java 21) fails to load on older JREs with a cryptic
UnsupportedClassVersionError — so a Java-version check inside such a class
is unreachable. By compiling the bootstrap at bytecode level 52 (Java 8), the
class loads on any JRE from Java 8 onward and can print a clear
"requires Java 21+" message before exiting. The module is tiny (~100 LoC),
depends only on java.base, and uses only APIs available in Java 8
(URLClassLoader, reflection, System.getProperty("java.specification.version")).
Generated by maven-appassembler-plugin during the build, not hand-written.
- POSIX:
jsignpdf.sh - Windows:
jsignpdf.cmd - Java lookup order:
JAVA_HOME→javaonPATH→ friendly error. - Minimum-Java-version check is done in the bootstrap class, not the script, so the error message is consistent across shells.
- DEB + RPM are produced by
jpackageon the Linux x64 and Linux aarch64 runners. Requiresfakeroot(DEB) andrpm-build(RPM) installed on the runner — both available onubuntu-24.04andubuntu-24.04-arm. - Flatpak keeps the current
org.freedesktop.Sdk.Extension.openjdkapproach. Manifest is updated to unpack the full ZIP as its source and set the JFX classpath at install time (the bootstrap class handles this uniformly). Build path stays separate from jpackage; Flathub conventions preserved; users benefit from shared OpenJDK security updates.
- PR: Linux x64 build + unit tests only. No packaging.
- Push: Linux x64 build + unit tests + Maven SNAPSHOTs deployment. (i.e. follow current approach)
- Release by
workflow_dispatch: full matrix (jars build → package matrix → release publish).
build-jars (ubuntu-24.04)
├─ mvn package (no shade)
├─ assemble minimal ZIP
├─ assemble full ZIP (all JFX classifiers)
└─ upload artifact: jsignpdf-jars
package (matrix, needs: build-jars)
├─ windows-2022 → MSI + Win ZIP (SignPath signs MSI)
├─ ubuntu-24.04 → DEB + RPM + Linux x64 ZIP
├─ ubuntu-24.04-arm → DEB + RPM + Linux aarch64 ZIP
└─ macos-14 → DMG + macOS aarch64 ZIP (unsigned, for now)
flatpak (ubuntu-24.04, needs: build-jars)
└─ flatpak-builder using full ZIP + openjdk extension
release (needs: package, flatpak)
├─ compute SHA-256 checksums
└─ upload all assets as workflow artifacts (manual attach to Release for now)
- Maven cache via
actions/setup-java@v4withcache: maven. Keyed onpom.xmlhash. fail-fast: falseso one platform failure does not abort the others mid-release.- No Intel macOS build. Apple discontinued Intel Macs in 2023; GitHub's
last Intel hosted image (
macos-13) is being retired and there is no newer Intel runner to migrate to.jpackageonly builds for the host arch, so an x64 DMG would require an Intel host. Intel Mac users run the Apple Silicon DMG under Rosetta 2 or use the cross-platform full ZIP. See3.1-separate-release-steps.mdfor the history (an earlier revision kept it as best-effort and probed for an optional self-hosted Intel mac). concurrency: ${{ github.ref }}so a re-tag cancels the previous run.- Pinned runner images (
ubuntu-24.04,macos-14,windows-2022) — not*-latest. - Free runners only: all listed runners (incl.
ubuntu-24.04-armandmacos-14) are free on public repos as of 2025. No paid minutes. - WiX 3 is preinstalled on
windows-2022; do notchoco install.
jsignpdf-<version>-windows-x64.msi
jsignpdf-<version>-windows-x64.zip
jsignpdf-<version>-linux-x64.deb
jsignpdf-<version>-linux-x64.rpm
jsignpdf-<version>-linux-x64.zip
jsignpdf-<version>-linux-aarch64.deb
jsignpdf-<version>-linux-aarch64.rpm
jsignpdf-<version>-linux-aarch64.zip
jsignpdf-<version>-macos-aarch64.dmg
jsignpdf-<version>-macos-aarch64.zip
jsignpdf-<version>-full.zip
jsignpdf-<version>-minimal.zip
jsignpdf-<version>-SHA256SUMS.txt
- Remove
maven-shade-pluginconfiguration fromjsignpdf/pom.xml. - Remove
-jar-with-dependenciesreferences from docs, README, website. - Add
maven-appassembler-pluginconfiguration for minimal + full ZIPs. - Add new
jsignpdf-bootstrapMaven module withBootstrap.java(~100 LoC, compiled at--release 8: Java-version check + JFX classifier detection + classloader assembly + reflective main invocation + Swing fallback hook). - Adapt
distribution/jpackage/anddistribution/windows/build-windows-installers.ps1to feed off the unshaded jars instead of the fat jar. - Update
distribution/linux/flatpakmanifest to consume the full ZIP. - Update README install instructions: link MSI / DEB / RPM / DMG / Flatpak per platform, ZIPs as fallback.
- Update website download page with the new artifact matrix.
- macOS signing / notarization (follow-up).
- SBOM / SLSA provenance.
- Windows arm64 (no demand signal yet; can be added later — Zulu+FX has a
Windows arm64 build, and GitHub offers
windows-11-armrunners).
- Bootstrap fallback policy: on JFX load failure in the full ZIP, keep the current behavior — show a warning dialog and fall back to Swing.
- DEB/RPM package name:
jsignpdf(matches existing install scripts). - Flatpak: build for both x64 and aarch64.