Guide to jlink – jlink指南

最后修改: 2019年 3月 23日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

jlink is a tool that generates a custom Java runtime image that contains only the platform modules that are required for a given application.

jlink 是一个生成自定义Java运行时映像的工具,该映像仅包含特定应用程序所需的平台模块。

Such a runtime image acts exactly like the JRE but contains only the modules we picked and the dependencies they need to function. The concept of modular runtime images was introduced in JEP 220.

这样的运行时映像与JRE的作用完全相同,但只包含我们挑选的模块和它们运行所需的依赖关系。模块化运行时映像的概念是在JEP 220中提出的。

In this tutorial, we’ll learn how to create a custom JRE using jlink, and we’ll also run and test that our module functions correctly inside our JRE.

在本教程中,我们将学习如何使用jlink创建一个自定义的JRE,我们还将运行并测试我们的模块在JRE中的功能是否正确。

2. Need to Create a Custom JRE

2.需要创建一个自定义的JRE

Let’s understand the motivation behind custom runtime images with an example.

让我们通过一个例子来理解自定义运行时图像背后的动机。

We’ll create a simple modular application. To know more about creating modular applications, please refer to our article on modularity.

我们将创建一个简单的模块化应用程序。要了解更多关于创建模块化应用程序的信息,请参考我们关于模块化的文章

First, let’s create a HelloWorld class and a corresponding module:

首先,让我们创建一个HelloWorld类和一个相应的模块。

public class HelloWorld {
    private static final Logger LOG = Logger.getLogger(HelloWorld.class.getName());
    public static void main(String[] args) {
        LOG.info("Hello World!");
    }
}
module jlinkModule {
    requires java.logging;
}

To run this program, we only need HelloWorld, String, Logger, and Object classes.

要运行这个程序,我们只需要HelloWorld, String, Logger, 和Object类。

Even though this program needs only four classes to run, all the predefined classes in the JRE also get executed, even if our program doesn’t require them.

尽管这个程序只需要四个类来运行,但JRE中所有预定义的类也被执行,即使我们的程序不需要它们。

Therefore, to run a small program, we have to maintain a complete JRE, which is simply a waste of memory.

因此,为了运行一个小程序,我们必须维护一个完整的JRE,这简直是在浪费内存。

So, a customized JRE is the best option to run our example.

因此,定制的JRE是运行我们的例子的最佳选择。

With jlink, we can create our own, small JRE that contains only the relevant classes that we want to use, without wasting memory, and as a result, we’ll see increased performance.

通过jlink,我们可以创建自己的、小型的JRE,其中只包含我们想要使用的相关类,而不会浪费内存,因此,我们会看到性能的提高。

3. Building Custom Java Runtime Images

3.构建自定义的Java运行时图像

We’ll perform a series of simple steps to create custom JRE images.

我们将执行一系列简单的步骤来创建自定义JRE图像。

3.1. Compiling a Module

3.1.编译一个模块

First, let’s compile the program mentioned above from the command line:

首先,让我们从命令行编译上面提到的程序。

javac -d out module-info.java
javac -d out --module-path out com\baeldung\jlink\HelloWorld.java

Now, let’s run the program:

现在,让我们运行该程序。

java --module-path out --module jlinkModule/com.baeldung.jlink.HelloWorld

The output will be:

输出结果将是。

Mar 13, 2019 10:15:40 AM com.baeldung.jlink.HelloWorld main
INFO: Hello World!

3.2. Using jdeps to List the Dependent Modules

3.2.使用jdeps来列出依赖模块

In order to use jlink, we need to know the list of the JDK modules that the application uses and that we should include in our custom JRE.

为了使用jlink,我们需要知道应用程序使用的JDK模块列表,以及我们应该包含在自定义JRE中的模块。

Let’s use the jdeps command to get the dependent modules used in the application:

让我们使用jdeps命令来获取应用程序中使用的依赖模块。

jdeps --module-path out -s --module jlinkModule

The output will be:

输出结果将是。

jlinkModule -> java.base
jlinkModule -> java.logging

This makes sense, as java.base is the minimum module needed for Java code libraries, and java.logging is used by a logger in our program.

这是有道理的,因为java.base是Java代码库所需的最小模块,而java.logging被我们程序中的记录器使用。

3.3. Creating a Custom JRE with jlink

3.3.用jlink创建一个自定义JRE

To create a custom JRE for a module-based application, we can use the jlink command. Here’s its basic syntax:

为了给基于模块的应用程序创建一个自定义的JRE,我们可以使用jlink命令。下面是它的基本语法。

jlink [options] –module-path modulepath
  –add-modules module [, module…]
  --output <target-directory>

Now, let’s create a custom JRE for our program using Java 11:

现在,让我们使用Java 11为我们的程序创建一个自定义JRE

jlink --module-path "%JAVA_HOME%\jmods";out
  --add-modules jlinkModule
  --output customjre

Here, the value after the –add-modules parameter tells jlink which module to include in the JRE.

这里,-add-modules参数后面的值告诉jlink哪个模块要包含在JRE中。

Finally, the customjre next to the –output parameter defines the target directory where our custom JRE should be generated.

最后,customjre旁边的-output参数定义了目标目录,我们的自定义JRE应该在这个目录下生成。

Note, we use Windows shell to execute all the commands throughout this tutorial. Linux and Mac users might have to slightly adjust them.

注意,我们在本教程中使用Windows shell来执行所有的命令。Linux和Mac用户可能要对它们进行轻微调整。

3.4. Running an Application with the Generated Image

3.4.用生成的图像运行一个应用程序

Now, we have our custom JRE created by jlink.

现在,我们有了由jlink创建的自定义JRE。

To test our JRE, let’s try to run our module by navigating inside the bin folder of our customjre directory and run the command below:

为了测试我们的JRE,让我们尝试运行我们的模块,在customjre目录下的bin文件夹内导航,并运行以下命令。

java --module jlinkModule/com.baeldung.jlink.HelloWorld

Again, the Windows shell, which we use, looks in the current directory for any executable before proceeding to the PATH. We need to pay extra attention to actually run our custom JRE, and not the java resolved against a PATH when we’re on Linux or Mac.

同样,我们使用的Windows shell在进入PATH之前会在当前目录中寻找任何可执行文件。我们需要格外注意实际运行我们的自定义JRE,而不是当我们在Linux或Mac上时针对PATH解决的java

4. Creating Custom JRE with Launcher Scripts

4.用Launcher Scripts创建自定义JRE

Optionally, we can also create a custom JRE with executable launcher scripts.

另外,我们还可以创建一个带有可执行启动器脚本的自定义JRE

For this, we need to run the jlink command that has an extra –launcher parameter to create our launcher with our module and main class:

为此,我们需要运行jlink命令,该命令有一个额外的-launcher参数,用我们的模块和主类创建我们的启动器

jlink --launcher customjrelauncher=jlinkModule/com.baeldung.jlink.HelloWorld
  --module-path "%JAVA_HOME%\jmods";out
  --add-modules jlinkModule
  --output customjre

This will generate two scripts: customjrelauncher.bat and customjrelauncher inside our customjre/bin directory.

这将产生两个脚本。customjrelauncher.batcustomjrelauncher在我们的customjre/bin目录下。

Let’s run the script:

让我们来运行这个脚本。

customjrelauncher.bat

And the output will be:

而输出将是。

Mar 18, 2019 12:34:21 AM com.baeldung.jlink.HelloWorld main
INFO: Hello World!

5. Conclusion

5.总结

In this tutorial, we have learned how we can create a custom, modular JRE with jlink that only contains the bare minimum files needed for our module. We also looked into how to create a custom JRE with launcher scripts that can be easily executed and shipped.

在本教程中,我们学习了如何用jlink创建一个自定义的、模块化的JRE,它只包含我们模块所需的最低限度的文件。我们还研究了如何用启动器脚本创建一个自定义的JRE,可以很容易地执行和运送。

Custom, modular Java runtime images are powerful. The goals for creating custom JREs are clear: they save on memory, improve performance, and also enhance security and maintainability. Lightweight custom JREs also enable us to create scalable applications for small devices.

自定义、模块化的Java运行时映像非常强大。创建自定义JRE的目标很明确:它们可以节省内存,提高性能,还能增强安全性和可维护性。轻量级的自定义JRE还使我们能够为小型设备创建可扩展的应用程序。

The code snippets used in this tutorial are available over Github.

本教程中使用的代码片段是通过Github提供的。