Is jlink The Future?

CodeFX Weekly #60 — 16th of March 2018

Hi everyone,

stressful week: I was at JavaLand, published a post on application class-data sharing (read to reduce app launch time by double digit percentages), and gave a NightHacking session about it (not yet online). I am preparing a Java 8 course for next week (did you know, you can hire me for in-house trainings?) and putting finishing touches in the book.

In between all of that I don’t really have time to write a newsletter, but there’s one topic, on which I don’t have to write much. Bonus points: It connects to last week’s newsletter.

I send this newsletter out every Friday. Yes, as an actual email. Subscribe!


Is jlink the future of Java deployments?

In last week’s newsletter I discussed Oracle’s Java Client Roadmap Update and quoted this blog post from last September (emphasis mine):

As client application development continues to shift from the old “plugin” world to modern deployment, the need for a standalone Java Runtime Environment (JRE) that is installed centrally, separately from Java applications has diminished. Using the ‘jlink’ tool introduced with JDK 9 will make it even easier for application developers to package and deploy dedicated runtimes rather than relying on a pre-installed system JRE. Oracle will begin transitioning from the standalone architecture later next year in what will be a multi-year effort.

The Java Module System contains an entire chapter about jlink and I think it's a really great tool. I'm just not convinced it's the be-all and end-all and I want to share why. First a quick overview, then my view on some of its downsides.


Introduction to jlink

Chapter 14 intro

One of the key motivations for discussing modularity in Java has always been what is now called the Internet of Things (IoT). This is true for OSGi, Java’s most widely used third-party module system, which set out in 1999 to improve the development of embedded Java applications, and also for Project Jigsaw, which developed the JPMS and aimed to make the platform more scalable by allowing the creation of very small runtimes with just the code an (embedded) application needs.

This is where jlink comes in. It's a Java command line tool (in your JDK's bin folder) that you can use to select a number of platform modules and link them into a runtime image. Such a runtime image acts exactly as a JRE but contains just the modules you picked and the dependencies they need to function (as indicated by requires directives). During that linking phase, jlink can be used to further optimize image size and improve VM performance, particularly startup time.

In the years since Jigsaw’s inception, a lot of things have changed, though. For one, disk space in embedded devices no longer comes at such a premium. At the same time we have seen the rise of virtualization, most prominently with Docker, where container size does once again become a concern (even if not a major one). The rise of containerization also brought the pressure to ease and automate deployment, which is nowadays done a few orders of magnitude more frequently.

And jlink helps here as well. It doesn't stop at linking platform modules--it can also create application images, which include app code as well as library and framework modules. This allows your build process to produce an entirely self-contained deployment unit that comprises your entire app with exactly the platform modules it needs, optimized for image size and performance as you see fit, launchable with a simple call to a native script.

If you’re more of a desktop application developer and your eyes glazed over when I mentioned IoT and Docker, that last bit should have made you sit up. With jlink it is exceedingly easy to ship a single ZIP file that users can launch without any further setup. And if you've been using javapackager, you'll be delighted to hear that it now calls jlink internally, giving you access to all its features (although I won't go into the integration--the javapackager documentation has you covered).

Security, performance, and stability of application images

Section 14.2.3

Creating an application image can increase your application’s security by minimizing the amount of code available in the JVM and thus reducing the attack surface. As section 14.4.3 discusses, you can also expect small improvements in startup time.

While that sounds pretty neat, it only fully applies to situations where you have complete control over the application’s operation and redeploy regularly. If you ship your image to customers or have otherwise no control over when and how often the image is replaced with a newer one, the tables turn.

An image generated with jlink is not built for modifications. It has no auto-update function and patching it manually is not a realistic scenario. If users update their system JRE, your application image will not be impacted by that. Taken together, that means it is forever bound to the exact Java version from which you took the platform modules during linking.

The upside is that JRE updates can’t break your application, but the much more serious downside is that your app will not benefit from any security patches or performance improvements the new Java version brings. Let that sink in. If a critical vulnerability is patched in a new Java version, your users will still be exposed until they deploy the new application image that you shipped.

If you decide to deliver application images, I recommend making this an additional delivery mechanism instead of the only one. Let users decide whether they want to deploy an entire image or prefer to run the JARs on their own runtime, over which they have full control and which they can update independently.



PS: Don’t forget to subscribe or recommend! :)

Photo by Kaley Dykstra on Unsplash