问题描述
我正在尝试使用Java 11构建并打包为jlink
的应用程序的跨平台存档.
I am trying to build cross-platform archives of an application built using Java 11 and packaged with jlink
.
对于跨平台打包,我的构建基于.我已经设法使Gradle构建下载目标平台的JDK并使用相应的jmods
文件夹调用jlink
,但是目标映像始终包含主机平台的二进制文件和JRE结构(在我的情况下为Windows,这意味着生成的bin
文件夹始终包含DLL和Windows可执行文件.如果我提供--strip-native-commands
标志,则尽管DLL仍然存在,但根本不包含任何可执行文件.
For the cross-platform packaging I am basing my build on this answer. I have managed to make my Gradle build download the target platform's JDK and invoke jlink
with the appropriate jmods
folder, however the target image always includes the binaries and JRE structure of the host platform (in my case Windows, meaning the generated bin
folder always includes DLLs and Windows executables). If I supply the --strip-native-commands
flag then no executables are included at all, although the DLLs still are.
有什么方法可以使jlink
打包正确的JRE文件?
Is there any way to make jlink
package the correct JRE files?
主机JDK: Windows Oracle JDK 11.0.10 x64
目标JDK: OpenJDK 11.0.2 x64
示例Linux调用:
C:\Program Files\Java\jdk-11.0.10/bin/jlink.exe
--module-path C:\projectdir\build\install\project-linux\lib;C:\projectdir\build\JREs\linux\jmods
--add-modules com.acme.app
--compress 2
--launcher app=com.acme.app/com.acme.app.Main
--no-header-files
--no-man-pages
--strip-debug
--dedup-legal-notices=error-if-not-same-content
--output C:\projectdir\build\packageFiles\linux
GraalVM
使用GraalVM CE Java 11 21.0.0
会产生:
java.io.IOException: Invalid JMOD file: C:\jdks\graalvm-ce-java11-21.0.0\jmods\java.base.jmod
这使得GraalVM的jlink
似乎总是尝试使用主机的JMOD文件.
Which makes it seem like GraalVM's jlink
always attempts to use the host's JMOD files.
OpenJDK
使用OpenJDK 11.0.2 x64
会产生与在创建的运行时映像中包含主机的二进制文件相同的结果.对于Zulu OpenJDK 11.0.10+9 x64
,也是相同的行为.
Using OpenJDK 11.0.2 x64
yields the same result of including the host's binary files in the created runtime image. The same behaviour is true for Zulu OpenJDK 11.0.10+9 x64
.
推荐答案
发现了问题:问题出在我对Linux和MacOS JDK发行版的jmods
目录的引用上.
Found the issue: the problem was with my reference to the jmods
directory of both the Linux and the MacOS JDK distributions.
对于Linux操作系统,我错误地将构建版本设置为下载版本11.0.1
而不是11.0.2
,这最终导致逻辑将层次结构扁平化而不是对其进行扁平化.这意味着build/JREs/linux/jmods
引用未针对任何现有文件夹,这意味着jlink
在此处找不到JDK模块,因此包含了主机文件.
For the Linux one I mistakenly setup the build to download version 11.0.1
instead of 11.0.2
, which ended up leading to the logic to flatten the hierarchy not flattening it. This means that the build/JREs/linux/jmods
reference wasn't targeting any existing folder, meaning that jlink
doesn't find the JDK modules there hence the host files being included.
MacOS JDK具有完全不同的文件结构,因此拼合逻辑只是错误的.最终,这会导致相同的jmods
文件夹症状消失.
The MacOS JDK has a completely different file structure so the flattening logic was just wrong. Ultimately this lead to the same missing jmods
folder symptom.
在两个问题均已修复的情况下,jlink
工具现在可以在构建跨平台运行时映像时正确打包目标JDK的文件.
With both issues fixed the jlink
tool now correctly packages the target JDK's files when building cross-platform runtime images.
这篇关于jlink打包当前平台的二进制文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!