In the previous article I quickly showed how to use jlink. However, this JRE will only work for platform on which it was generated. So how can we build for Windows, Mac OS X and Linux?
It would be easy, therefore, to assume that you need a Windows machine to build for Windows, a Mac for OS X and Linux for Linux. But not everyone has, or even wants all platforms.
Solving for Linux is easy using VMs, but there’s a much easy way!
All that is required to generate a JRE is the jmods folder (and jlink tool as part of the jdk). The beauty of this is that we can download the JDKs for other platforms and make use of those jmods.
What is a jmod? Well, it’s a new packaging format in Java 9+ that is used for modules that can be required at compile. They can also include resources.
The JMOD file format let’s you aggregate files other than
.classfiles, metadata, and resources. This format is transportable but not executable, which means that you can use it during compile time or link time but not at run time.1
Using jmods with jlink
Having downloaded the JDKs for other platforms, we can tell jlink which jmods to use to create the JRE. By default, the jmods part of jlink’s JDK will be used.
In the last article, we used “–module-path out/production” when using jlink, which automatically added my platform’s jmods to the module path. If we point to the jmods in the other JDKs, jlink will produce a JRE for that platform.
jlink --module-path "<path-to-windows-jdk>\jmods;out\production" --add-modules uk.co.jennettwheeler.hello_world --output out/hellojre-windows
jlink --module-path "<path-to-linux-jdk>\jmods;out\production" --add-modules uk.co.jennettwheeler.hello_world --output out/hellojre-linux
Mac OS X
jlink --module-path "<path-to-osx-jdk>\jmods;out\production" --add-modules uk.co.jennettwheeler.hello_world --output out/hellojre-osx
By changing just one path, we have completely changed the output. Windows has .exe and .ddl files, linux has binaries and .so files, and Mac has binaries and .dylib files.
If you run these on each platform, you should see “Hello World” printed to the console.
out\hellojre-windows\bin\java -m uk.co.jennettwheeler.hello_world/uk.co.jennettwheeler.hello_world.HelloWorld > Hello World
out/hellojre-linux/bin/java -m uk.co.jennettwheeler.hello_world/uk.co.jennettwheeler.hello_world.HelloWorld > Hello World
Mac OS X
out/hellojre-osx/bin/java -m uk.co.jennettwheeler.hello_world/uk.co.jennettwheeler.hello_world.HelloWorld > Hello World
And there you have it. An ability to create a custom JRE for each platform from one development machine.
If you wish to save on storage space, you can delete all the files in the alternate platform JDKs except the jmod folder as they are not needed by jlink.
I build these JREs on my Windows Machine (as can be deduced from the back slashed file paths). So, if using a Unix system, be sure to specify forward slashes in your paths and use a colon (:) instead if a semi-colon to specify multiple paths. You’ll see me account for this in the next article which will be about automating the build process using maven, Bitbucket Pipelines, and Docker.