Java Runtimes with jlink

Microsoft acknowledges and supports the adoption of custom Java runtimes crafted for specific application needs rather the use of general purpose Java runtimes. This method of Java deployment ensures the Java runtime only contains the parts of the Java platform that are truly needed by applications, therefore increasing security, reducing deployment size, and enhancing performance, for both Cloud and server based Java applications as well as desktop/GUI applications.

Traditionally, Oracle/Sun Microsystems would produce Java Runtime Environment (JRE) installers which would contain solely the Java Virtual Machine, the Java APIs, and OS and browser specific integrations, aimed at enabling computers for running Java applications downloaded from the Internet, or for running Applets and Java Web Start applications through the browser.

With the advent of modern web applications and browsers, both Applets and Java Web Start technologies became deprecated, and browsers no longer support Java plugins. The need for a general purpose Java Runtime Environments pre-installed on computers became less significant overtime. With Java 9, the Applet API became deprecated (see JEP 289) and with Java 17, the API became marked for removal, meaning it will certainly be removed on a future release of Java.

Another significant change is the modularization of Java, also started with the Java 9 release (see JSR 376). As part of this change, developers can now use a newly added command line in the JDK called jlink to produce a custom Java runtime specifically designed to fit the needs of applications, to be deployed as a built-in embedded runtime along with the application code often times as part of a container image for Cloud-based workloads, or as part of installers for GUI-based applications.

Today, Minecraft: Java Edition is deployed to millions of Minecraft gamers with a custom Java runtime embedded within the game. Behind online services such as LinkedIn, Yammer, Bing, and Azure, Microsoft also deploys hundreds of thousands of JVMs using this technique.

Create a custom Java runtime

To create a Java runtime, you must have JDK 9 or later installed on your environment. Download and install the Microsoft Build of OpenJDK first.

Identify required modules with jdeps

The Java Platform is now segmented into modules. See the documentation of Java 17 for a full list; other versions of Java may include new modules.

The JDK tool jdeps can be used to analyze a .class file, a directory, or a JAR file, to identify Java module dependencies, JDK internals dependencies, and other useful information that will help developers produce Java runtimes.

$ cat HelloWorld.java
public class HelloWorld {
  public static void main(String args[]) {
    System.out.println("Hello World!");
  }
}

$ jdeps HelloWorld.class
HelloWorld.class -> java.base
   <unnamed>                                          -> java.io                                            java.base
   <unnamed>                                          -> java.lang                                          java.base

The tool jdeps indicates that this class only depends on types in the java.lang and java.io packages, therefore it only needs the module java.base. A similar output would be produced for a JAR file as input. With a list of the required modules, you can now create a Java runtime.

To create a Java runtime from the JDK, you must know which modules you want. Use jdeps to identify them. For details on the jlink command line tool, please see the documentation.

Example:

$ jlink \
         --add-modules java.base \
         --strip-debug \
         --no-man-pages \
         --no-header-files \
         --compress=2 \
         --output /javaruntime

You can now use the Java runtime located at /javaruntime to execute the application code dependent on java.base module. The structure of the javaruntime folder produced by jlink is similar to the JDK directory structure, and the java command line tool to start the JVM, is located in the ./bin/ folder as usual. Given a custom Java runtime contains all the required modules of an existing application, it can be referenced by JAVA_HOME.

$ /javaruntime/bin/java HelloWorld
Hello, World!

In the example above, the produced Java runtime on Windows consumes about 24 MB on Windows.

Create a Java runtime with Docker container image

You can use Docker multi-stage builds to create, consume, and pack the custom Java runtime as part of your image build. See how to create Java runtimes using Docker.

Knowledge base

javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure

Visit Java Security and Cryptography for an explanation on how to fix this issue.

Resources

Provide feedback on the Microsoft Build of OpenJDK

Send us your comments, thoughts, and ideas to help us improve the Microsoft Build of OpenJDK. Visit our OpenJDK discussions page on GitHub to send us your feedback.

Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.