使用 jlink 自定义 Java 运行时环境

Red Hat build of OpenJDK 11

Red Hat Customer Content Services

摘要

Red Hat build of OpenJDK 11 是 Red Hat Enterprise Linux 平台上的红帽产品。使用 jlink 自定义 Java 运行时镜像 指南提供了 Jlink 的概述,并解释了如何使用 jlink 创建和使用自定义 Java 运行时镜像。

使开源包含更多

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。我们从这四个术语开始:master、slave、黑名单和白名单。由于此项工作十分艰巨,这些更改将在即将推出的几个发行版本中逐步实施。详情请查看 CTO Chris Wright 的信息

对红帽文档提供反馈

我们感谢您对我们文档的反馈。要提供反馈,您可以突出显示文档中的文本并添加注释。

本节介绍如何提交反馈。

先决条件

  • 已登陆到红帽客户门户网站。
  • 在红帽客户门户中,以多页 HTML 格式查看文档。

流程

要提供反馈,请执行以下步骤:

  1. 点文档右上角的反馈按钮查看现有的反馈。

    注意

    反馈功能仅在多页 HTML 格式中启用。

  2. 高亮标记您要提供反馈的文档中的部分。
  3. 点在高亮文本旁弹出的 Add Feedback

    文本框将在页面右侧的"反馈"部分中打开。

  4. 在文本框中输入您的反馈,然后点 Submit

    创建了一个与文档相关的问题。

  5. 要查看问题,请单击反馈视图中的问题跟踪器链接。

第 2 章 为非模块化应用程序创建自定义 Java 运行时环境

您可以使用 jlink 工具从非模块化应用程序创建自定义 Java 运行时环境(JRE)。

先决条件

流程

  1. 使用 Logger 类创建一个简单的 Hello World 应用。

    1. 您有基础红帽构建的 OpenJDK 11 在 jdk-11 文件夹中:

      $ 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)
    2. 为应用程序创建一个目录:

      $ mkdir -p hello-example/sample
    3. 使用以下内容创建 hello-example/sample/HelloWorld.java 文件:

      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!");
          }
      }
    4. 编译应用程序:

      $ ./jdk-11/bin/javac -d . $(find hello-example -name \*.java)
    5. 在没有自定义 JRE 的情况下运行 您的应用程序:

      $ ./jdk-11/bin/java sample.HelloWorld
      Mar 09, 2021 10:48:59 AM sample.HelloWorld main
      INFO: Hello World!

      在这种情况下,OpenJDK 的基本构建需要 311 MB 来运行单个类。

    6. (可选) 您可以检查红帽构建的 OpenJDK,并为您的应用程序查看许多非必需的模块:

      $ 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.10

      Hello World 应用示例存在非常少的依赖项。您可以使用 jlink 为应用程序创建自定义运行时镜像。这些镜像可帮助您只使用红帽构建的 OpenJDK 依赖项运行应用程序。

  2. 使用 jdeps 命令确定应用程序的模块依赖项:

    $ ./jdk-11/bin/jdeps -s ./sample/HelloWorld.class
    HelloWorld.class -> java.base
    HelloWorld.class -> java.logging
  3. 为您的应用程序构建自定义 java 运行时镜像:

    $ ./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.10
    注意

    自定义 java 运行时镜像的大小从 313M 运行时镜像减少到 50M 运行时镜像。

  4. 您可以验证应用程序的运行时减少:

    $ ./custom-runtime/bin/java sample.HelloWorld
    Jan 14, 2021 12:13:26 PM HelloWorld main
    INFO: Hello World!

    生成的 JRE 和您的示例应用程序没有任何其他依赖项。

    您可以将应用程序与自定义运行时一起分发用于部署。

注意

使用基础红帽构建 OpenJDK 的每个安全更新,为您的应用程序重建自定义 java 运行时镜像。

第 3 章 为模块化应用程序创建自定义 Java 运行时环境

您可以使用 jlink 工具从模块化应用程序创建自定义 Java 运行时环境。

先决条件

流程

  1. 使用 Logger 类创建一个简单的 Hello World 应用。

    1. 您有基础红帽构建的 OpenJDK 11 在 jdk-11 文件夹中:

      $ 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)
    2. 为应用程序创建一个目录:

      $ mkdir -p hello-example/sample
    3. 使用以下内容创建 hello-example/sample/HelloWorld.java 文件:

      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!");
          }
      }
    4. 使用以下内容创建 hello-example/module-info.java 文件:

      module sample
      {
          requires java.logging;
      }
    5. 编译应用程序:

      $ ./jdk-11/bin/javac -d example $(find hello-example -name \*.java)
    6. 在没有自定义 JRE 的情况下运行 您的应用程序:

      $ ./jdk-11/bin/java -cp example sample.HelloWorld
      Mar 09, 2021 10:48:59 AM sample.HelloWorld main
      INFO: Hello World!

      在这种情况下,OpenJDK 的基本构建需要 311 MB 来运行单个类。

    7. (可选) 您可以检查红帽构建的 OpenJDK,并为您的应用程序查看许多非必需的模块:

      $ 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.10

      Hello World 应用示例存在非常少的依赖项。您可以使用 jlink 为应用程序创建自定义运行时镜像。这些镜像可帮助您只使用红帽构建的 OpenJDK 依赖项运行应用程序。

  2. 创建应用程序模块:

    $ 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.jmod
  3. 使用所需模块创建自定义 JRE,并为您的应用程序创建自定义应用程序启动程序。

    $ ./jdk-11/bin/jlink --launcher hello=sample/sample.HelloWorld --module-path sample-module --add-modules sample --output custom-runtime
  4. 列出生成的自定义 JRE 的模块。

    请注意,只有一部分原始红帽构建的 OpenJDK 会保留。

    $ 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.0
    注意

    自定义 java 运行时镜像的大小从 313M 运行时镜像减少到 50M 运行时镜像。

  5. 使用 hello launcher 启动应用。

    $ ./custom-runtime/bin/hello
    Jan 14, 2021 12:13:26 PM HelloWorld main
    INFO: Hello World!

    您的示例应用程序生成的 JRE 没有 java.basejava.loggingsample 模块以外的任何其他依赖项。

    您可以在 custom-runtime 中发布与自定义运行时捆绑的应用程序。它包括您的应用程序。

注意

使用基础红帽构建 OpenJDK 的每个安全更新,为您的应用程序重建自定义 java 运行时镜像。

更新于 2023-09-20

法律通告

Copyright © 2023 Red Hat, Inc.
The text of and illustrations in this document are licensed by Red Hat under a Creative Commons Attribution–Share Alike 3.0 Unported license ("CC-BY-SA"). An explanation of CC-BY-SA is available at http://creativecommons.org/licenses/by-sa/3.0/. In accordance with CC-BY-SA, if you distribute this document or an adaptation of it, you must provide the URL for the original version.
Red Hat, as the licensor of this document, waives the right to enforce, and agrees not to assert, Section 4d of CC-BY-SA to the fullest extent permitted by applicable law.
Red Hat, Red Hat Enterprise Linux, the Shadowman logo, the Red Hat logo, JBoss, OpenShift, Fedora, the Infinity logo, and RHCE are trademarks of Red Hat, Inc., registered in the United States and other countries.
Linux® is the registered trademark of Linus Torvalds in the United States and other countries.
Java® is a registered trademark of Oracle and/or its affiliates.
XFS® is a trademark of Silicon Graphics International Corp. or its subsidiaries in the United States and/or other countries.
MySQL® is a registered trademark of MySQL AB in the United States, the European Union and other countries.
Node.js® is an official trademark of Joyent. Red Hat is not formally related to or endorsed by the official Joyent Node.js open source or commercial project.
The OpenStack® Word Mark and OpenStack logo are either registered trademarks/service marks or trademarks/service marks of the OpenStack Foundation, in the United States and other countries and are used with the OpenStack Foundation's permission. We are not affiliated with, endorsed or sponsored by the OpenStack Foundation, or the OpenStack community.
All other trademarks are the property of their respective owners.