Build your own custom Java Runtime with jlink and jdeps

Since Java 9, the way Java programs are supposed to be distributed changed.

It used to be that users would install a Java Runtime Environment (JRE) on their system.  The user then gets the Java app from the app developer.  The Java app then runs on the JRE that's installed.

Some OS like Macs used to even have a "system" JRE installed as part of the OS.

The world's moved on from that style of app distribution.  Nowadays, many users want statically compiled programs, or a single executable file with no dependencies.  For better or worse.

That means when you develop a Java app and want to distribute it, it's on you as the developer to create your own custom Java Runtime and package that runtime together with the rest of your app for distribution.

The upshot is that if you don't use too much of the Java standard library and customize your Java Runtime, then you pay for only what you use in terms of the size of the Java runtime you need to package with your app.

You can find what Java modules your app depends on using jdeps easily: jdeps my.jar

Then you can use jlink to create the Java Runtime your app needs: jlink --output my-custom-runtime --add-modules java.base,and.other.modules

Then you can run your app with the custom Java Runtime: /path/to/my-custom-runtime/bin/java -jar my.jar

The Java Runtime that jlink creates is specific to the OS platform you ran jlink on.  So on Windows, you'll have to substitute java.exe for java in the path above.

There's a way to cross-compile a Java Runtime for a different OS platform with jlink, but you'll need to download the target platform's JDK.  It was easier to run the target platform's OS in a virtual machine and run jlink on it instead.

A thorough and detailed tutorial is How to Create Java Runtime Images with jlink.

No comments: