Using jlink to cross-compile minimal JREs
21–30 of 66 posts
Re: Using jlink to cross-compile minimal JREs
#22It's a pity that system wide JREs are not a thing anymore. I understand that it was difficult to get an updated JRE on the system in the early 2000s, but nowadays almost every computer is online - certainly one where you are currently downloading an application on - and automatic updates are commonplace. You used to be able to just double click on a .jar, and that was a Java application. And it would be trivial engin…
Re: Using jlink to cross-compile minimal JREs
#23Not customizing the runtime per build or per app also potentially helps reuse of docker image layers across your container registries and clusters.
Re: Using jlink to cross-compile minimal JREs
#24These days, all Java runtimes are created with jlink, including the one that's bundled in the JDK, so it's worth it to take a few minutes to learn how to do it yourself for a custom image. The result is not only drastically smaller, but more secure, as the potential attack surface area is much smaller. If your application is modularised, it can become a part of the image, but, as the article shows, creating a custom…
Stuff like Hibernate, Spring, the big libraries.
How easy is it for the average greenfield enterprise to start as a modular app?
How easy is it for the average brownfield enterprise app started 10 years ago to convert to a modular app?
Re: Using jlink to cross-compile minimal JREs
#25You don't need to run jlink yourself to avoid shipping the entire JDK. Here's a java19 runtime docker image at 62MB: https://hub.docker.com/_/eclipse-temurin/tags?page=1&name=19... Not customizing the runtime per build or per app also potentially helps reuse of docker image layers across your container registries and clusters.
Not everyone wants that.
Re: Using jlink to cross-compile minimal JREs
#26JLink 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…
Or maybe other HNers, have you used it?
Re: Using jlink to cross-compile minimal JREs
#27Earlier quoted context omitted.
No. You are thinking of GraalVM native image which will compile java to native machine code. jlink is more similar to tree shaking: it strips the JRE of anything your program don't need.
But I think the parent's point is given reflection, how can jlink statically know the complete set of classes that your program needs?
Re: Using jlink to cross-compile minimal JREs
#28These days, all Java runtimes are created with jlink, including the one that's bundled in the JDK, so it's worth it to take a few minutes to learn how to do it yourself for a custom image. The result is not only drastically smaller, but more secure, as the potential attack surface area is much smaller. If your application is modularised, it can become a part of the image, but, as the article shows, creating a custom…
How is modularization progressing in practice? Stuff like Hibernate, Spring, the big libraries. How easy is it for the average greenfield enterprise to start as a modular app? How easy is it for the average brownfield enterprise app started 10 years ago to convert to a modular app?
> How easy is it for the average greenfield enterprise to start as a modular app?
As easy as a non-modularised one.
> How easy is it for the average brownfield enterprise app started 10 years ago to convert to a modular app?
This one is harder to answer because you can only modularise (i.e. encapsulate in modules) code that is actually modular (cleanly separates API and implementation into different packages, no circular dependencies among components that are to become modules etc.). So it depends on how modular your codebase already is. In many situations it could require a not-insignificant refactoring, and so worth it if you really want the best security and encapsulation (which was the case for the JDK itself, which is now fully modularised). In other situations it could make sense to leave things alone and only modularise new project components (modules and code outside modules can mix).
Either way, modular or not, using link to produce a custom runtime is a good idea!
Re: Using jlink to cross-compile minimal JREs
#29JLink 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…
I 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?
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.
Re: Using jlink to cross-compile minimal JREs
#30With this setup, deliveries would look a bit like the following:
# SIZE WHAT
1 ~100 MB base OS image (reused if not changed, cached)
2 ~340 MB JDK image (reused if not changed, cached)
3 X MB the app .jar file (changes with every release)
Whereas with the approach in the article, it would look a bit like the following: # SIZE WHAT
1 ~100 MB base OS image (reused if not changed, cached)
2 Y MB minimal JRE + the app (changes with every release)
For example, consider the example in the article: 36M zulu-hello-jre-linux-x64
338M zulu19.30.11-ca-jdk19.0.1-linux_x64
While it's hard to speak of how any given app would look like if it was just a .jar (or what other real world examples would be like, not just a "Hello world" program), it would only take 10 individual releases to exceed the size of the JDK. In this case, if you deploy once every day, then by the end of the first month, you'd be using ~2X more space for the minimal JRE approach. However, if you would update your JDK version more than once a month, then that might as well go out of the window.So it appears that it all depends on how much you care about space in the first place, as well as what technologies you use, since the above example only seems relevant for container technologies that have the whole layer mechanism, and only then if you don't squash them for up front space savings for individual container images. On the other hand, if you update your base image and/or the runtime often, then using jlink makes a lot of sense, since the approach with the separate JDK would send the whole thing often anyways.