从 jlink 运行时镜像中剥离调试信息

Photo by Nuno Silva

使用 jlink,可以轻松创建自定义 Java 运行时镜像,该镜像仅包含运行给定应用程序所需的模块。 jlink 还附带一些附加插件,其中一些插件将有助于进一步减小生成的自定义运行时镜像的大小,即 compressstrip-debug 插件。

顾名思义,strip-debug 插件将从输出运行时镜像中删除调试信息。在 JDK13 中,此插件仅从输出镜像的类中剥离 Java 调试属性。从 JDK13 开始,它已更新为更精细,现在除了 Java 调试属性之外,还能够从输出自定义镜像中删除本机调试符号。

要调用它,只需使用其中一个 strip*debug* 标志附加 jlink 命令,但请注意 JDK13 中的行为差异。

例如 jlink --module-path mlib --strip-debug --add-modules com.greetings --output myappruntime

JDK13 之前的行为

  • —-strip-debug:剥离 Java 调试属性。

JDK13+ 行为

  • —-strip-debug:组合调试剥离,即删除 Java 调试属性 ( —-strip-java-debug-attributes) 本机调试符号 (--strip-native-debug-symbols)。

  • —-strip-java-debug-attributes:剥离 Java 调试属性。

  • —-strip-native-debug-symbols:剥离本机调试符号。

要删除本机调试符号,strip-debug 插件依赖于本机 Linux objcopy 实用程序。如果它未安装(例如,在 Alpine Linux 上)或安装在非标准位置,您将收到以下异常

java.io.IOException: Cannot run program “objcopy”: error=2, No such file or directory

您可以通过指定 objcopy 的路径来解决此问题

jlink … --strip-native-debug-symbols objcopy=/usr/bin/objcopy …

当针对不同的平台时,这尤其有用。

注意事项

  • 某些版本(例如 Oracle OpenJDK 版本Oracle JDK 版本)已剥离 Java 调试属性,因此 —-strip-java-debug-attributes 对这些版本几乎没有用处。

  • objcopy=<path> 仅适用于 --strip-native-debug-symbols,不适用于 —-strip-debug

  • —-strip-native-debug-symbols—-strip-debug 是互斥的。

  • 剥离本机调试符号是与平台相关的,目前仅在 Linux 上受支持。

结论

改进的运行时大小在容器中运行 Java 应用程序时尤其重要,因为保持容器映像较小是关键。此外,避免携带永远不会使用的位始终是一种好习惯。`jlink 是每个 Java 开发人员都应考虑利用以实现此目的的工具。

最初发布在 Medium 上。