Using jlink to customize Java runtime environment
Abstract
Providing feedback on Red Hat build of OpenJDK documentation Copy linkLink copied to clipboard!
To report an error or to improve our documentation, log in to your Red Hat Jira account and submit an issue. If you do not have a Red Hat Jira account, then you will be prompted to create an account.
Procedure
- Click the following link to create a ticket.
- Enter a brief description of the issue in the Summary.
- Provide a detailed description of the issue or enhancement in the Description. Include a URL to where the issue occurs in the documentation.
- Clicking Submit creates and routes the issue to the appropriate documentation team.
Making open source more inclusive Copy linkLink copied to clipboard!
Red Hat is committed to replacing problematic language in our code, documentation, and web properties. We are beginning with these four terms: master, slave, blacklist, and whitelist. Because of the enormity of this endeavor, these changes will be implemented gradually over several upcoming releases. For more details, see our CTO Chris Wright’s message.
Chapter 1. Overview of jlink Copy linkLink copied to clipboard!
Jlink is a Java command line tool that is used to generate a custom Java runtime environment (JRE). You can use your customized JRE to run Java applications.
Using jlink, you can create a custom runtime environment that only includes the relevant class file.
Chapter 2. Creating a custom Java runtime environment for non-modular applications Copy linkLink copied to clipboard!
You can create a custom Java runtime environment (JRE) from a non-modular application using the jlink tool.
Prerequisites
Install Red Hat build of OpenJDK 11.
NoteIt is always recommended to use the portable tarball as a basis of jlink’ed runtime.
Procedure
Create a simple Hello World application using Logger class.
You have the base Red Hat build of OpenJDK 11 available in the
jdk-11folder:$ ls jdk-11 bin conf demo include jmods legal lib man NEWS release $ ./jdk-11/bin/java -version openjdk version "11.0.10" 2021-01-19 LTS OpenJDK Runtime Environment 18.9 (build 11.0.10+9-LTS) OpenJDK 64-Bit Server VM 18.9 (build 11.0.10+9-LTS, mixed mode)Create a directory for your application:
$ mkdir -p hello-example/sampleCreate
hello-example/sample/HelloWorld.javafile with the following content:package sample; import java.util.logging.Logger; public class HelloWorld { private static final Logger LOG = Logger.getLogger(HelloWorld.class.getName()); public static void main(String[] args) { LOG.info("Hello World!"); } }Compile your application:
$ ./jdk-11/bin/javac -d . $(find hello-example -name \*.java)Run your application without a custom JRE:
$ ./jdk-11/bin/java sample.HelloWorld Mar 09, 2021 10:48:59 AM sample.HelloWorld main INFO: Hello World!In this case, the base Red Hat build of OpenJDK takes 311 MB to run a single class.
(Optional) You can inspect the Red Hat build of OpenJDK and see many non-required modules for your application:
$ du -sh jdk-11/ 313M jdk-11/$ ./jdk-11/bin/java --list-modules java.base@11.0.10 java.compiler@11.0.10 java.datatransfer@11.0.10 java.desktop@11.0.10 java.instrument@11.0.10 java.logging@11.0.10 java.management@11.0.10 java.management.rmi@11.0.10 java.naming@11.0.10 java.net.http@11.0.10 java.prefs@11.0.10 java.rmi@11.0.10 java.scripting@11.0.10 java.se@11.0.10 java.security.jgss@11.0.10 java.security.sasl@11.0.10 java.smartcardio@11.0.10 java.sql@11.0.10 java.sql.rowset@11.0.10 java.transaction.xa@11.0.10 java.xml@11.0.10 java.xml.crypto@11.0.10 jdk.accessibility@11.0.10 jdk.aot@11.0.10 jdk.attach@11.0.10 jdk.charsets@11.0.10 jdk.compiler@11.0.10 jdk.crypto.cryptoki@11.0.10 jdk.crypto.ec@11.0.10 jdk.dynalink@11.0.10 jdk.editpad@11.0.10 jdk.hotspot.agent@11.0.10 jdk.httpserver@11.0.10 jdk.internal.ed@11.0.10 jdk.internal.jvmstat@11.0.10 jdk.internal.le@11.0.10 jdk.internal.opt@11.0.10 jdk.internal.vm.ci@11.0.10 jdk.internal.vm.compiler@11.0.10 jdk.internal.vm.compiler.management@11.0.10 jdk.jartool@11.0.10 jdk.javadoc@11.0.10 jdk.jcmd@11.0.10 jdk.jconsole@11.0.10 jdk.jdeps@11.0.10 jdk.jdi@11.0.10 jdk.jdwp.agent@11.0.10 jdk.jfr@11.0.10 jdk.jlink@11.0.10 jdk.jshell@11.0.10 jdk.jsobject@11.0.10 jdk.jstatd@11.0.10 jdk.localedata@11.0.10 jdk.management@11.0.10 jdk.management.agent@11.0.10 jdk.management.jfr@11.0.10 jdk.naming.dns@11.0.10 jdk.naming.ldap@11.0.10 jdk.naming.rmi@11.0.10 jdk.net@11.0.10 jdk.pack@11.0.10 jdk.rmic@11.0.10 jdk.scripting.nashorn@11.0.10 jdk.scripting.nashorn.shell@11.0.10 jdk.sctp@11.0.10 jdk.security.auth@11.0.10 jdk.security.jgss@11.0.10 jdk.unsupported@11.0.10 jdk.unsupported.desktop@11.0.10 jdk.xml.dom@11.0.10 jdk.zipfs@11.0.10Sample
Hello Worldapplication has very few dependencies. You can use jlink to create custom runtime images for your application. These images help you run your application with only required Red Hat build of OpenJDK dependencies.
Determine module dependencies of your application using
jdepscommand:$ ./jdk-11/bin/jdeps -s ./sample/HelloWorld.class HelloWorld.class -> java.base HelloWorld.class -> java.loggingBuild a custom java runtime image for your application:
$ ./jdk-11/bin/jlink --add-modules java.base,java.logging --output custom-runtime $ du -sh custom-runtime 50M custom-runtime/ $ ./custom-runtime/bin/java --list-modules java.base@11.0.10 java.logging@11.0.10NoteThe size of your custom java runtime image is being reduced to 50M runtime image from 313M runtime image.
You can verify the reduced runtime of your application:
$ ./custom-runtime/bin/java sample.HelloWorld Jan 14, 2021 12:13:26 PM HelloWorld main INFO: Hello World!The generated JRE with your sample application does not have any other dependencies.
You can distribute your application together with your custom runtime for deployment.
Rebuild the custom java runtime images for your application with every security update of your base Red Hat build of OpenJDK.
Chapter 3. Creating a custom Java runtime environment for modular applications Copy linkLink copied to clipboard!
You can create a custom Java runtime environment from a modular application using the jlink tool.
Prerequisites
Install Red Hat build of OpenJDK 11.
NoteIt is always recommended to use the portable tarball as a basis of Jlink’ed runtime.
Procedure
Create a simple Hello World application using Logger class.
You have the base Red Hat build of OpenJDK 11 available in the
jdk-11folder:$ ls jdk-11 bin conf demo include jmods legal lib man NEWS release $ ./jdk-11/bin/java -version openjdk version "11.0.10" 2021-01-19 LTS OpenJDK Runtime Environment 18.9 (build 11.0.10+9-LTS) OpenJDK 64-Bit Server VM 18.9 (build 11.0.10+9-LTS, mixed mode)Create a directory for your application:
$ mkdir -p hello-example/sampleCreate
hello-example/sample/HelloWorld.javafile with the following content:package sample; import java.util.logging.Logger; public class HelloWorld { private static final Logger LOG = Logger.getLogger(HelloWorld.class.getName()); public static void main(String[] args) { LOG.info("Hello World!"); } }Create
hello-example/module-info.javafile with the following content:module sample { requires java.logging; }Compile your application:
$ ./jdk-11/bin/javac -d example $(find hello-example -name \*.java)Run your application without a custom JRE:
$ ./jdk-11/bin/java -cp example sample.HelloWorld Mar 09, 2021 10:48:59 AM sample.HelloWorld main INFO: Hello World!In this case, the base Red Hat build of OpenJDK takes 311 MB to run a single class.
(Optional) You can inspect the Red Hat build of OpenJDK and see many non-required modules for your application:
$ du -sh jdk-11/ 313M jdk-11/$ ./jdk-11/bin/java --list-modules java.base@11.0.10 java.compiler@11.0.10 java.datatransfer@11.0.10 java.desktop@11.0.10 java.instrument@11.0.10 java.logging@11.0.10 java.management@11.0.10 java.management.rmi@11.0.10 java.naming@11.0.10 java.net.http@11.0.10 java.prefs@11.0.10 java.rmi@11.0.10 java.scripting@11.0.10 java.se@11.0.10 java.security.jgss@11.0.10 java.security.sasl@11.0.10 java.smartcardio@11.0.10 java.sql@11.0.10 java.sql.rowset@11.0.10 java.transaction.xa@11.0.10 java.xml@11.0.10 java.xml.crypto@11.0.10 jdk.accessibility@11.0.10 jdk.aot@11.0.10 jdk.attach@11.0.10 jdk.charsets@11.0.10 jdk.compiler@11.0.10 jdk.crypto.cryptoki@11.0.10 jdk.crypto.ec@11.0.10 jdk.dynalink@11.0.10 jdk.editpad@11.0.10 jdk.hotspot.agent@11.0.10 jdk.httpserver@11.0.10 jdk.internal.ed@11.0.10 jdk.internal.jvmstat@11.0.10 jdk.internal.le@11.0.10 jdk.internal.opt@11.0.10 jdk.internal.vm.ci@11.0.10 jdk.internal.vm.compiler@11.0.10 jdk.internal.vm.compiler.management@11.0.10 jdk.jartool@11.0.10 jdk.javadoc@11.0.10 jdk.jcmd@11.0.10 jdk.jconsole@11.0.10 jdk.jdeps@11.0.10 jdk.jdi@11.0.10 jdk.jdwp.agent@11.0.10 jdk.jfr@11.0.10 jdk.jlink@11.0.10 jdk.jshell@11.0.10 jdk.jsobject@11.0.10 jdk.jstatd@11.0.10 jdk.localedata@11.0.10 jdk.management@11.0.10 jdk.management.agent@11.0.10 jdk.management.jfr@11.0.10 jdk.naming.dns@11.0.10 jdk.naming.ldap@11.0.10 jdk.naming.rmi@11.0.10 jdk.net@11.0.10 jdk.pack@11.0.10 jdk.rmic@11.0.10 jdk.scripting.nashorn@11.0.10 jdk.scripting.nashorn.shell@11.0.10 jdk.sctp@11.0.10 jdk.security.auth@11.0.10 jdk.security.jgss@11.0.10 jdk.unsupported@11.0.10 jdk.unsupported.desktop@11.0.10 jdk.xml.dom@11.0.10 jdk.zipfs@11.0.10Sample
Hello Worldapplication has very few dependencies. You can use jlink to create custom runtime images for your application. These images help you run your application with only required Red Hat build of OpenJDK dependencies.
Create your application module:
$ mkdir sample-module $ ./jdk-11/bin/jmod create --class-path example/ --main-class sample.HelloWorld --module-version 1.0.0 -p example sample-module/hello.jmodCreate a custom JRE with the required modules and a custom application launcher for your application.
$ ./jdk-11/bin/jlink --launcher hello=sample/sample.HelloWorld --module-path sample-module --add-modules sample --output custom-runtimeList the modules of the produced custom JRE.
Observe that only a fraction of the original Red Hat build of OpenJDK remains.
$ du -sh custom-runtime 50M custom-runtime/ $ ./custom-runtime/bin/java --list-modules java.base@11.0.10 java.logging@11.0.10 sample@1.0.0NoteThe size of your custom java runtime image is being reduced to 50M runtime image from 313M runtime image.
Launch the application using the
hellolauncher.$ ./custom-runtime/bin/hello Jan 14, 2021 12:13:26 PM HelloWorld main INFO: Hello World!The generated JRE with your sample application does not have any other dependencies other than
java.base,java.logging, andsamplemodule.You can distribute your application bundled with the custom runtime in
custom-runtime. It includes your application.
Rebuild the custom java runtime images for your application with every security update of your base Red Hat build of OpenJDK.
Revised on 2024-05-09 16:48:50 UTC