Java,自从在 linux 移至 Java 14 后无法执行 spawn helper 错误

Java, Failed to exec spawn helper error since moving to Java 14 on linux

刚刚从 Java 11 移动到 Java 14

以下代码现在在 linux 机器上失败:

String linux_exe  = System.getProperty("user.dir") + '/' + "fpcalc_arm32";
List<String> params = new ArrayList();
params.add(linux_exe);
params.add("-plain");
params.add("-length");
params.add(submittedSongLength);
params.add(file.getPath());
Process p = Runtime.getRuntime().exec(params.toArray(new String[1]));                    

使用堆栈跟踪

Cannot run program "/mnt/system/config/Apps/SongKong/songkong/fpcalc_arm32": error=0, Failed to exec spawn helper: pid: 13998, exit value: 127
java.io.IOException: Cannot run program "/mnt/system/config/Apps/SongKong/songkong/fpcalc_arm32": error=0, Failed to exec spawn helper: pid: 13998, exit value: 127
at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1128)
at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1071)
at java.base/java.lang.Runtime.exec(Runtime.java:590)
at java.base/java.lang.Runtime.exec(Runtime.java:449)
at com.jthink.songkong.analyse.acoustid.AcoustId.generateFingerprint(AcoustId.java:217)
at com.jthink.songkong.analyse.acoustid.AcoustId.createAcoustIdFingerprint(AcoustId.java:106)

在 Java 14 中发生了什么变化会导致这种情况?

我 运行 在 Windows 上使用 java 14 的等效代码 运行 没问题。但是我已经使用 Java 11 和 Java 14 在这台 unix 机器上重试了相同的代码库,并且可以确认 Java 11 总是有效 Java14总是失败

我发现了这个问题,我在 Openjdk 错误数据库上遇到了这些问题

Provide a way for Runtime.exec to use posix_spawn on linux

Change the Process launch mechanism default on Linux to be posix_spawn

基本上在 Java 11 Linux 使用 vfork 来启动进程但是通过 Java 13 现在使用 posix_spawn

posix_spawn 实际上需要一个名为 jspawnhelper 的程序,该程序位于 jre/lib 中。在我的例子中,它存在,但它没有执行权限,这是因为我使用 jlink 构建了一个只包含我需要的系统模块的 jre,但我在 [=47= 上创建了它](我的主要开发环境)。

call "C:\Program Files\AdoptOpenJDK\jdk-11.0.6.10-hotspot\bin\jlink" --module-path="C:\Code\jthink\SongKong\linux_jdk\jmods"  --add-modules java.desktop,java.datatransfer,java.logging,java.management,java.naming,java.net.http,java.prefs,java.scripting,java.sql,jdk.management,jdk.unsupported,jdk.scripting.nashorn --output C:\code\jthink\songkong\linuxjre

Windows 不理解 linux 执行权限,当我部署我的应用程序时,我对 jre/bin 中的可执行文件设置了执行权限,但不知道有任何jre/lib 中的可执行文件。更改 jspawnhelper 的执行权限修复了这个问题。

另一种解决方法是添加以下 java 选项:

-Djdk.lang.Process.launchMechanism=vfork