在 macOS 应用程序中嵌入打包为 jlink 图像的 Java 应用程序
Embedding a Java application packaged as a jlink image in a macOS app
我正在尝试将 Java 应用程序嵌入本机 Mac 应用程序。 Java 应用程序与 jlink (Java 9+) 打包在一起,包括一个精简的 JRE。
我正在尝试使用 Java 调用接口创建 JVM 并启动主程序 class,但程序在调用 JNI_CreateJavaVM
时崩溃,因为找不到 libjava.dylib
.
在我的 Xcode 项目中,我有一个 "Copy Files" 阶段将整个 jlink 图像(包含 bin
、lib
等目录的文件夹)复制到应用程序包,进入 Contents/image
目录。
$ ls -l Java\ Native\ Wrapper.app/Contents/image/
total 8
drwxr-xr-x 11 ahs staff 352 Jan 13 12:46 bin
drwxr-xr-x 6 ahs staff 192 Jan 13 12:46 conf
drwxr-xr-x 25 ahs staff 800 Jan 13 12:46 legal
drwxr-xr-x 52 ahs staff 1664 Jan 13 12:46 lib
-rw-r--r-- 1 ahs staff 717 Jan 13 12:46 release
dylib 文件在那里:
$ file Java\ Native\ Wrapper.app/Contents/image/lib/libjava.dylib
Java Native Wrapper.app/Contents/image/lib/libjava.dylib: Mach-O 64-bit dynamically linked shared library x86_64
我的 Objective-C 代码链接到 lib/jli/libjli.dylib
中的 JNI 库。 Xcode 自动将其复制到应用程序包的 Frameworks 目录中。
当我 运行 程序时,我在控制台上收到以下错误:
Error: could not find libjava.dylib
Failed to GetJREPath()
我将 image/lib
目录添加到 运行 时间搜索路径。用 otool
检查二进制文件确认:
$ otool -l Java\ Native\ Wrapper
...
Load command 18
cmd LC_RPATH
cmdsize 48
path @executable_path/../Frameworks (offset 12)
Load command 19
cmd LC_RPATH
cmdsize 48
path @executable_path/../image/lib (offset 12)
...
我真的被难住了。我试过将 dylib 复制到 Frameworks 目录,但没有用。
我做错了什么?
它应该工作得很好。如果我创建用户特定变量 - JAVA_HOME
(User-Defined Settings
) 并将其设置为指向 Java.
基于 jlink
的版本
JAVA_HOME
: $(HOME)/tmp/jdk-13-stripped
然后,我确保添加:$(JAVA_HOME)/jdk-13-stripped/lib
作为资源(它将在最终应用程序的 Resources
目录中结束),然后,我设置以下设置:
Run Search Paths: @executable_path/../Resources/lib/server
Header Search Paths: $(JAVA_HOME)/include and $(JAVA_HOME)/include/darwin
Library Search Paths: $(JAVA_HOME)/lib/server
Other Linker Flags: -L$(JAVA_HOME)/lib/server -ljvm
然后,我运行代码
> ./CallJVM
Hello from Java
如果我检查加载了哪个图像,它是从正确的位置获取的
> lldb CallJVM
(lldb) image list
...
...
[ 7] .... .../Debug/CallJVM.app/Contents/Resources/lib/server/libjvm.dylib
更新
如果有人需要与此主题相关的视频教程,请点击此处:Embedding JVM inside macOS application bundle (using XCode)
我正在尝试将 Java 应用程序嵌入本机 Mac 应用程序。 Java 应用程序与 jlink (Java 9+) 打包在一起,包括一个精简的 JRE。
我正在尝试使用 Java 调用接口创建 JVM 并启动主程序 class,但程序在调用 JNI_CreateJavaVM
时崩溃,因为找不到 libjava.dylib
.
在我的 Xcode 项目中,我有一个 "Copy Files" 阶段将整个 jlink 图像(包含 bin
、lib
等目录的文件夹)复制到应用程序包,进入 Contents/image
目录。
$ ls -l Java\ Native\ Wrapper.app/Contents/image/
total 8
drwxr-xr-x 11 ahs staff 352 Jan 13 12:46 bin
drwxr-xr-x 6 ahs staff 192 Jan 13 12:46 conf
drwxr-xr-x 25 ahs staff 800 Jan 13 12:46 legal
drwxr-xr-x 52 ahs staff 1664 Jan 13 12:46 lib
-rw-r--r-- 1 ahs staff 717 Jan 13 12:46 release
dylib 文件在那里:
$ file Java\ Native\ Wrapper.app/Contents/image/lib/libjava.dylib
Java Native Wrapper.app/Contents/image/lib/libjava.dylib: Mach-O 64-bit dynamically linked shared library x86_64
我的 Objective-C 代码链接到 lib/jli/libjli.dylib
中的 JNI 库。 Xcode 自动将其复制到应用程序包的 Frameworks 目录中。
当我 运行 程序时,我在控制台上收到以下错误:
Error: could not find libjava.dylib
Failed to GetJREPath()
我将 image/lib
目录添加到 运行 时间搜索路径。用 otool
检查二进制文件确认:
$ otool -l Java\ Native\ Wrapper
...
Load command 18
cmd LC_RPATH
cmdsize 48
path @executable_path/../Frameworks (offset 12)
Load command 19
cmd LC_RPATH
cmdsize 48
path @executable_path/../image/lib (offset 12)
...
我真的被难住了。我试过将 dylib 复制到 Frameworks 目录,但没有用。
我做错了什么?
它应该工作得很好。如果我创建用户特定变量 - JAVA_HOME
(User-Defined Settings
) 并将其设置为指向 Java.
jlink
的版本
JAVA_HOME
: $(HOME)/tmp/jdk-13-stripped
然后,我确保添加:$(JAVA_HOME)/jdk-13-stripped/lib
作为资源(它将在最终应用程序的 Resources
目录中结束),然后,我设置以下设置:
Run Search Paths: @executable_path/../Resources/lib/server
Header Search Paths: $(JAVA_HOME)/include and $(JAVA_HOME)/include/darwin
Library Search Paths: $(JAVA_HOME)/lib/server
Other Linker Flags: -L$(JAVA_HOME)/lib/server -ljvm
然后,我运行代码
> ./CallJVM
Hello from Java
如果我检查加载了哪个图像,它是从正确的位置获取的
> lldb CallJVM
(lldb) image list
...
...
[ 7] .... .../Debug/CallJVM.app/Contents/Resources/lib/server/libjvm.dylib
更新
如果有人需要与此主题相关的视频教程,请点击此处:Embedding JVM inside macOS application bundle (using XCode)