jlink is more similar to tree shaking: it strips the JRE of anything your program don't need.
jlink is more similar to tree shaking: it strips the JRE of anything your program don't need.
Final binary size is naturally vastly reduced b/c you won't have the whole JRE, but last I tested you still end up with very chunky executables (minimal JFX GUIs were coming out to 100-200 MB)
But to just say "no reflection" and tree shake your JVM code - not that I'm aware of unfortunately! I'd love to just treeshake entire unused dependencies. At the moment I do it manually - but it's a chore and it's hard to do comprehensively.
Now that post- Java8 you're supposed to jlink the JRE, I somehow doubt this will ever happen. The people that care about executable size would probably be doing Graal Native.
You do need to manually annotate classes used by reflection so it doesn't remove (or obfuscate) them.
conveyor generate javafx com.example.jfx-test && cd jfx-test
./gradlew jar
conveyor make windows-app
du -h output
71mb on disk. 31mb package size. That's a bit bigger than strictly necessary. It includes FXML and see the discussion of optional plugin modules elsewhere.However you can easily get to 150-200mb on disk by using javafx.web because that includes a custom build of WebKit which is ~75mb all by itself.
> It includes FXML and see the discussion of optional plugin modules elsewhere.
Where is this?
And do you know if it's still not possible to generate an .exe? I remember that while I was turned off by the final files sizes, what really made me drop jlink was that the final built target would always be some baroque installer (which makes sense for large GUIs that need to maintain state between runs). But you couldn't just generate a double-clickeable .exe or .appimage file that'd be equivalent to running your uberjar. So I stuck to the uberjar.. (now user have problem installing weird Java 11 Runtimes from not-Oracle)
(Further confusing things was that there is some intermediary build target in jlink also called `appimage` that's not actually an appimage, but it's quite similar..)
jlink itself just outputs a directory tree. If you want the user to be able to double click an exe then there are several options but two are:
1. Use Gluon Native Image. This will AOT compile your Java code and statically link JavaFX to give you a genuine single EXE program, with no JVM, no JIT compilation, and fast startup. However your app needs to be native-image compatible and I don't know if every app turns into a single EXE.
2. Use (surprise) Conveyor, which will make an EXE that when opened downloads, installs and then immediately runs your app using a bundled JVM. If your app is already installed then it'll do an update check and then open it. And of course your app can be then invoked from the start menu.
The latter isn't genuinely a single EXE of course but the UX is similar and it handles the common case of needing to update either your app, or your JVM, or both.