我正在为 Mac 计算机创建一个 JAVA 桌面应用程序,使用 jpackage 将所需的 JRE 捆绑到应用程序中,最后将 .app 发送给客户。
对于新的 m1 Apple Arm 硅计算机,我不想使用正确的 JRE(Intel 和 Arm)为每个处理器架构创建不同的应用程序,而是创建一个通用二进制应用程序,在 Intel 计算机上启动 Intel JRE,在 Intel 计算机上启动 Arm JRE手臂计算机。我知道这是可能的。
我尝试创建两个 .apps 并从 mac 命令行使用 lipo 工具,但这实际上不起作用。
有什么建议如何继续吗?
我采用了 Zulu Intel 和 Arm JRE(不是 JDK)构建并对二进制文件进行了 lipo'ed。您可以使用生成的 JRE 包运行该脚本(您只需要在 Intel 和 ARM 计算机上运行 jpackage 即可为每种架构获取适当的运行时)。
Github 仓库:
https://github.com/ChristopherBruno78/universal_jre
在 Intel 和 Arm macOS 13 Ventura 上测试。
所以我遵循了这个非常详细的教程:
https://incenp.org/notes/2023/universal-java-app-on-macos.html
经过一些小的改动后,它可以在 Intel(使用 Mac OS 11)和 Apple 芯片(使用 Mac OS 14)上完美运行。我尝试了所有三个选项,但将使用最后一个带有 2 个线程的选项。
我在使用旧操作系统的机器上编译了该文件。
两点小意见: 函数 get_application_directory 需要稍微修复一下:
static char * get_application_directory(char *buffer, uint32_t len)
{
char *last_slash = NULL;
int n = 2;
if ( ! _NSGetExecutablePath(buffer, &len) ) {
while ( n-- > 0 ) {
if ( (last_slash = strrchr(buffer, '/')) )
*last_slash = '\0';
}
}
return last_slash ? buffer : NULL;
}
只有当我将每个 jar 文件放在类路径上并且不使用任何通配符 * 时,类路径上的 jar 引用才有效。
要进行调试,您始终可以调用此方法来打印 JVM 抛出的任何异常:
void check_and_print_exception(JNIEnv *env) {
if ((*env)->ExceptionCheck(env)) {
(*env)->ExceptionDescribe(env);
(*env)->ExceptionClear(env);
}
}