3

Java 中的 jlink 功能允许您为应用程序创建单独的运行时环境。通常,这个应用程序所需的所有模块都被 jlink 压缩到一个大的“模块”文件中。

我有兴趣找出是否有办法省略一些模块,以便它们是单独的 jar 文件,但这样 jlink 将能够找到它们并仍然运行应用程序。有没有办法做到这一点?

例如,如果您正在处理 LGPL 库,则这种情况的一个用例是。您可能希望将 LGPL 库排除在模块的巨大“blob”之外并将其作为单独的 jar 保留,以便想要将 jar 交换为不同版本/调整版本的人可以(这是 LGPL 要求的) .

Jlink 有一个“需要静态”语句,您可以使用它来要求可选模块。我认为使用它可能会起作用,但我遇到了这个问题。

当我用需要静态编译一个项目时,我已经能够通过使用 java 的“--add-modules”开关包含模块来运行它。但是,一旦我在其上运行 jlink 以创建自定义图像,我就无法让它工作。

当我尝试运行 jlinked 项目时,我得到 ClassNotFound 异常。

当您在项目上运行 jlink 时,它会创建一个自定义运行时映像。项目的所有主要模块都放入一个名为 modules 的图像文件中。我已经使用 jimage 命令检查了这个图像文件,并且我已经确认这个图像文件不包含我声明为静态的模块。

使用 jlink,我尝试将静态声明的模块中的 jar 文件放入带有模块映像的目录中。然后我尝试使用“--add-modules”手动添加模块,以及使用-p和-cp来指定带有jar的目录,但我仍然得到一个ClassNotFound异常。

4

1 回答 1

2

好的,我在发布后不久就回答了我自己的问题。

我学到了两件事:

  1. 制作 jlink 运行时映像后,您的单独 jars(需要静态模块)不能与 jlink 映像放在同一个 libs 目录中。

也就是说,jlink运行后,你会得到这样的目录结构: bin conf include legal lib

lib 文件夹是存储运行时映像的位置。我将单独的 jar 放在 lib 文件夹中,但这不起作用。如果你把它们放在一个单独的目录中,那么这是可行的。

  1. “-add-modules”开关必须放在序列中的 -m 命令之前才能运行映像。

运行映像的最终命令可能如下所示:

java --add-modules org.example.module.here,org.example.another.module.here -p your_jar_directory_here -m your.main.module/your.package.here.Main

这对我有用。您必须为 add-modules 开关提供包含您静态包含的模块的模块,并为 -p 开关提供包含这些模块的 jar 的目录的路径。

于 2019-04-20T15:55:08.473 回答