4 ms·
JLink is a pretty nice tool - easy to use and understand, relatively fast, big app size wins. A few misc thoughts: Figuring out what modules you need to ship c
by mike_hearn 4y ago
JLink is a pretty nice tool - easy to use and understand, relatively fast, big app size wins. A few misc thoughts:
Figuring out what modules you need to ship can be done with the jdeps tool, but, you have to watch out for some gotchas. One is that you have to run it on each JAR or set of jars. It's slow so it helps to do this incrementally. Another is that some critical JVM functions are implemented as 'plugins' that are loaded reflectively, and the static analysis won't find them. The one that trips up my users the most is jdk.crypto.ec which implements elliptic curve cryptography. The Java TLS stack will be present but fail to connect to many TLS servers nearly at random if this module is missing. Nonetheless it still needs less configuration than a typical ProGuard/R8/native-image style dead code elimination analysis.
JLink can replace JARs with an optimized file format called "jimage". It uses a very interesting perfect hash algorithm to minimize the number of seeks/page faults required to find a class or file and it also creates a unified string table. So the space savings come not only from deleting dead code but also reducing the space required. Unfortunately it only works for JARs that are explicitly modularized (with a module-info.class file). Slowly more modules are getting this but most still don't. A good improvement would be to use the jimage format for everything. It also does a bunch of other optimizations, for startup time and the like. Also you have to figure out which modules are modular and put them on the module path at link time. There are some build system plugins that can help with that but they mostly don't do cross-linking.
Final thing to realize is that jlink doesn't create a bundled app. It just shrinks and customizes the JVM for your app. To allow your app to start up, be installed etc requires other stuff.
Conveyor [1] has extensive support for jlink. You can name a JDK or it will learn from your Gradle build, then it'll download the JMOD files you need for each platform, run jdeps on all your JARs incrementally, figure out which modules are explicit, figure out which modules are broken and have to be put on the classpath, add back the TLS ECC support, allow you to override all these decisions via config, run jlink for each target OS and architecture, finally bundle up the results in self-updating packages for each OS and do it all in parallel. It's doing a lot of work but the result is pretty magical - you just take the JARs from your build system e.g. via the Gradle plugin, feed it to the tool and out pops a nicely optimized set of downloads with HTML download page for your cross-platform app.
[1] https://hydraulic.software/ https://hydraulic.software/
- oblio 4y agoI know that you're hawking your own software, but it looks quite cool. However, I wouldn't want to be a pioneer. Who uses it and for what? Do you have testimonials? Or maybe other HNers, have you used it?
- mike_hearn 4y agoWe now have a brands and testimonials section! https://hydraulic.software/ https://hydraulic.software/
- mike_hearn 4y agoYeah, hawking things is a bit of a new world to me. Good timing for the question, though. We've been collecting testimonials just last week and have a brands block for the website ready to go, pending one more approval. So that's coming RSN. Some firms who said we can point to their usage of it (these are all JVM based): - HEBI Robotics. They make robot kits and ship apps that allow you to control them with Conveyor. - GoToTags. They make NFC tags and just launched an app to work with them. - IonSpin. "mementō is a simple and modern file management solution". They aren't fully launched yet I think. - AdCentral. An app for managing various kinds of ad campaigns in physical stores (if I understood correctly). There are others, that's just a subset of the ones we've asked for testimonials. There's also some open source projects that use it. So far there's definitely a theme of apps that do things with specialist hardware, which isn't a big surprise. We also dogfood it for systemd managed servers, but that's kinda experimental. I'm still trying to figure out if there's anything useful to do there, like to go from a build.gradle to a set of pushed/updated servers in one step without Docker (or maybe with Docker). Like it'd make a linked standalone app, upload the files to the server(s), integrate it with systemd then start the apps. But maybe nobody would find that useful. Server ops is such a heavily invested-in space already.
- mwcampbell 4y agoSpeaking of JVM 'plugins' that are loaded reflectively, don't forget the Java Access Bridge on Windows, as I reported to Hydraulic some months ago. (Fortunately, that one is fixed in Conveyor.)