Presumably the major issue in distributing JavaFX applications (or most Java 9+ applications in general) is dealing with jlink. That leads to the problem in question: having to create N * M executable blobs, where N = # of operating systems and M = # of CPU architectures.
You don't need to do JLink for JavaFX. FX requires binary libraries, but you can make "platform specific" uber jars (and, probably, generic uber jars) that bundle correct libraries.
SQLite bundles all of the platforms into a single jar file, for example.
But that's another reason, at least for me, to look at the maven wrapper. Maven will "download the right thing" and not "burden" folks with copies of libraries they don't need. FX binaries can be quite big, particularly if you include WebKit (which I do simply for easy in app documentation, it's just a fat pig of a dependency though).
Yeah, seems to work for games well enough. Ship uberjar + small wrapper shellscript for Linux/macOS, .bat for Windows. Should work everywhere*
SnapCode: https://www.jdeploy.com/~snapcodejava
Because JReleaser is a release tool and not a build tool you are free to build however it’s needed, collect all artifacts and release them. I do this for the Ikonli JavaFX browser: build the app with Gradle which bundles platform specific JARs, then release them with JReleaser.
https://github.com/kordamp/ikonli Shows how it can be done. Requires building with GH Actions in multiple platforms.
For a "cross platform, portable system" it was just...ugh.
These are hobby projects. I struggle enough to make progress on them at all, much less dealing with tooling and what not (which I do not enjoy). Since my last project was a smashing success (I think 2-3 people downloaded it), it makes that extra hurdle to get installers working that much less interesting to me.
My next project I can leverage the work I did on my last one, to lower the burden. But clearly I would need to look into Github Actions (which I know nothing about) to get the cross platform binaries for machines I do not have. For my last project I installed Windows and Linux VMs to do my builds.
This JReleaser looks compelling, and maybe will make that kind of thing even easier with their examples.
Maybe my next project will be compelling enough to its audience to generate more traffic to justify the packaging effort.
Conveyor is free to use for open source projects and works how you'd hope it works: it's a signup/account-free downloadable CLI tool. You run a single command from your dev laptop (or a cheap Linux CI worker) and it builds/signs all the packages for every target OS and CPU architecture in one go, uploads them, and integrates the app with a native auto update engine. Sparkle on macOS, MSIX on Windows, an apt repository for Debian/Ubuntu users. It'll even make a download HTML page for you that detects the user's platform and gives a big green download button.
There's a bunch of sample apps showing how to integrate it into your {Electron,JavaFX,Compose for Desktop,native} app. "conveyor generate javafx my-sample-app" will spit out scaffolding that uses Gradle, and there's a Gradle plugin to import all the build info into Conveyor too. End result is you do:
./gradlew jar && conveyor make copied-site
And a new version of your app is released, existing users will start to update. That's all there is to it. It'll use jlink, jdeps and so on to make an optimized bundled JVM for your app. The big remaining pain is still code signing - Conveyor understands all the signature formats and protocols natively and will handle all that, but you do need to buy certificates. If you don't it'll make self signed apps which can be distributed and used but which will require the user to bypass various warnings.With its large user base, I would have expected Java to have figured out all the details and offered users a single command-line tool that automatically builds the project into installers. I had adventures with relatable pain points when figuring out how to distribute Julia's GUI applications.
Another upcoming difficulty is transitioning to distributing applications that run in the sandbox. Windows has MSIX, Linux has Snap and Flatpack, and macOS has DMGs signed with entitlements. Each has its way of configuring and how it is expected to work, and debugging sandboxing issues is no fun.
I made an application bundler specifically for Julia's MSIX, Snap, and DMG applications, which allows the use of the underlying configuration files when configuring the sandbox via a simple recipe system. Unlikely one would change languages, but perhaps some inspiration can be taken from my project:
Now we have MacOS ARM, MacOS x86, Linux ARM/x86, Windows ARM/x86.
Even for a basic "cross platform" Java program (that bundles the JRE), that's 6 installs, which ostensibly need to be built on their respective platforms. Add on to that if you using something that includes a binary (like, say, SQLite, much less JavaFX which I work with).
The release burden is, well, frankly, daunting for a small project.
My honest thinking for my next project release is simply to tell folks to install the JDK, download the source code, and have them run:
(Or they can run go.sh/go.bat which essentially does the same thing.)That'll download all of the stuff it needs including the Maven runtime and all of the libraries, as appropriate, build the project, and run it. It's Fast Enough (maybe it's awful on a small RPi, I dunno).
When I get more than 5 downloads, folks can vote as to which installer to work on.
Creating the executables was quite the black hole. I didn't create one for Linux because I honestly didn't know what packaging scheme to use.
In theory, the CI infrastructure on GitHub will let you build on different platforms, yet another black hole of time to sink into.
So, yea, at least initially, I think the maven wrapper will be my "release model". SHOULD be pretty simple.