Skip to content

Latest commit

 

History

History
217 lines (172 loc) · 9.92 KB

File metadata and controls

217 lines (172 loc) · 9.92 KB

3.1 — Drop the fat jar, ship per-platform distributions

Tracking: #391

Motivation

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).

Deliverables per release

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.

Windows EXE installer

Dropped. jpackage MSI provides the same double-click UX plus enterprise deployability. SignPath signing already targets MSI.

macOS signing / notarization

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.

Windows signing

MSI is signed via SignPath.io (already wired in the current pipeline; reuse as-is).

JDK

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).

Cross-platform ZIPs

Minimal ZIP

  • 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.

Full ZIP

  • 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) reads os.name + os.arch and picks the matching JFX classifier set, (3) assembles a URLClassLoader, (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")).

Launcher scripts (ZIPs)

Generated by maven-appassembler-plugin during the build, not hand-written.

  • POSIX: jsignpdf.sh
  • Windows: jsignpdf.cmd
  • Java lookup order: JAVA_HOMEjava on PATH → friendly error.
  • Minimum-Java-version check is done in the bootstrap class, not the script, so the error message is consistent across shells.

Linux: DEB / RPM / Flatpak

  • DEB + RPM are produced by jpackage on the Linux x64 and Linux aarch64 runners. Requires fakeroot (DEB) and rpm-build (RPM) installed on the runner — both available on ubuntu-24.04 and ubuntu-24.04-arm.
  • Flatpak keeps the current org.freedesktop.Sdk.Extension.openjdk approach. 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.

CI / release pipeline

Triggers

  • 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).

Workflow shape

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)

Optimization

  • Maven cache via actions/setup-java@v4 with cache: maven. Keyed on pom.xml hash.
  • fail-fast: false so 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. jpackage only 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. See 3.1-separate-release-steps.md for 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-arm and macos-14) are free on public repos as of 2025. No paid minutes.
  • WiX 3 is preinstalled on windows-2022; do not choco install.

Versioning and naming

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

Migration / removal checklist

  • Remove maven-shade-plugin configuration from jsignpdf/pom.xml.
  • Remove -jar-with-dependencies references from docs, README, website.
  • Add maven-appassembler-plugin configuration for minimal + full ZIPs.
  • Add new jsignpdf-bootstrap Maven module with Bootstrap.java (~100 LoC, compiled at --release 8: Java-version check + JFX classifier detection + classloader assembly + reflective main invocation + Swing fallback hook).
  • Adapt distribution/jpackage/ and distribution/windows/build-windows-installers.ps1 to feed off the unshaded jars instead of the fat jar.
  • Update distribution/linux/flatpak manifest 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.

Out of scope for 3.1

  • 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-arm runners).

Decisions

  • 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.