Hacker News new | past | comments | ask | show | jobs | submit login

> you unfortunately are semi-required to build platform specific bundles

Can you elaborate on this? It seems like a build tool specific issue to me. In Clojure, most projects use Leiningen (a build tool) and uberjars regardless of the target Java version will bundle native libraries for every platform you run on. You can exclude some of the libraries from your uberjar, but it's a manual process. This has an obvious drawback (e.g. depending on the SQLite JDBC driver bloats your JAR with dozens of native libraries), but it's still very much "build once, run everywhere".

The closest I've been to "platform specific bundles" was dealing with a Gradle project where the developer hard-coded a target platform into a property, thus making it impossible to bundle libraries for multiple platforms.




Right, both lein and depstar (or whatever the latest deps.edn one is) make uberjars. And this works great on Linux - which I'm pretty sure is the dev platform for almost all Clojurists. Linux distros basically always come with a OpenJDK JRE/JVM. But installing a JRE is actually discouraged by the Java people. You will notice on java.com you can't actually download a Java 11/17/+ JRE. You can only get a Java 8 JRE!

You're supposed to use `jpackage`. It basically packages up the uberjar with all the necessary pieces of the JRE to run the uberjar (so a pared down JRE) and does platform specific bundling like adding meta data and creating an installer (so your application can have a place to save settings and whatnot between runs, have an icon in the Start menu/desktop and stuff like that)

You can still do uberjars and get a JRE for Windows/Mac from third parties like Adaptium, but it's very unergonomic and looks kinda sketch (b/c it doesn't look official)

My own anecdotal experience:

I distributed a JavaFX/Java-17 app as an uberjar. My rational was:

- I didn't need any app persistence between runs, so I just wanted a small double-clickage ".exe/bin" equivalent that people could download and try out (no one wants install some random app to try out from online).

- `jpackage` doesn't allow you to make a simple double-clickable .exe (they can make something confusingly called an appimgage, which is not an Linux appimage - but it's similar!)

- I had no way to do testing on Mac b/c I don't own an Apple machine. So I don't wanna be generating Mac executables I can't even test.. At least with the uberjar I can be semi-confident if it runs on my laptop it'll run on a Mac later (sorta true)

The end result was a disaster.. 90% of user issues were from people that would who would go to java.com, "install Java" (ending up with a Java 8 JRE!) and then the app would just silently not run. The JRE doesn't produce any friendly error or warning saying anything about versions - it just silently fails. I have in bold on my landing page YOU NEED A JAVA 17+ JRE. No use.. people would still do it wrong


Yeah java isn't really used for Consumer apps and this is one of the reasons. The ones that do evade this problem by bundeling their own JVM.


No, consumer java desktop applications were already uncommon when java 9 came out.


More broadly, non-Electron apps have been uncommon for a while. I just don't work in the webspace and I need to write code that's relatively performant b/c it involves some numbercrunching. I understand it's all possible with Electron.. but it's a bit daunting to have a client-server web stack and multiple languages with some stuff in a local backend.. It's all a bit beyond me

JavaFX was a nice solution that's crossplatform and near-native. It has a very nice react-like library in Clojure called `cljfx`

https://github.com/cljfx/cljfx/


You're doing it wrong. Like way wrong.

Use jlink. It creates a double-clickable .exe from your JDK installation, pared down to a JRE for distribution. Works on Linux and Windows.


could you give me a link on how it's done? I looked into this extensively and there was no way to bundle an .exe . It was a 2-3 years ago so maybe things have changed


jlink only creates a runtime (the parts of the JDK that are actually used by your app), but there's a relatively new command called jpackage for creating installers: https://docs.oracle.com/en/java/javase/21/jpackage/packaging...

EDIT: I see now that you already know jpackage, but you don't want an installer. In that case you can use launch4j, which just wraps a jar in an exe: https://launch4j.sourceforge.net/


okay, Launch4j is new to me - but this seems to only work for Windows

I find the whole situation a bit silly, bc obviously it's creating an executable under the hood somewhere. The official tools just don't expose it to you.

I think what I could do is to run the installers on all target systems and then pull out the executables manually. I just think that'd be a bit difficult/annoying to make as part of a CI system


I only used Launch4j on Windows, but in the downloads you can find Linux and MacOS versions as well. At the bottom of the webpage it explains that it can be built on even more platforms, if you have MinGW binutils 2.22 (windres and ld only) on those platforms.

If I remember correctly, you can't just pull out the exe created by jpackage, because it doesn't contain the runtime. The installer installs both the runtime and the exe. The exe created by Launch4j also doesn't include the runtime, but Launch4j is better at finding a system-wide runtime, and can direct the user to a specific download site (such as adoptium.net) instead of java.com. If you want to have JUST a single exe, then I think GraalVM's native image is the only option.


Hmmm,yeah I should really just try GraalVM. JavaFX finally supports it. I just remmeber it was a bit unclear how to hook it up with Clojure/deps.edn but I'm sure the tooling has evolved since I last looked

Some day they'll integrate cosmopolitan builds with Graal native and we'll come full circle to cross-platform executables haha

Edit : https://github.com/oracle/graal/issues/4854


I think in your case it is actually javafx that makes packaging harder than necessary.

Not affiliated, but hydraulic conveyor is quite good at packaging stuff like this to a single exe.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: