Java,由于在Linux上迁移到Java 14,因此无法执行生成帮助程序错误

2022-09-04 21:19:00

刚刚从 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 中有什么变化会导致这种情况?

我使用java 14在Windows上运行了等效代码,并且运行良好。但是我在这个Unix机器上使用相同的代码库重新尝试了Java 11和Java 14,并且可以确认Java 11始终有效Java 14总是失败。


答案 1

我已经找到了这个问题,我在Openjdk Bugs数据库上遇到了这些问题

为 Runtime.exec 提供一种在 linux 上使用 posix_spawn的方法

将 Linux 上的进程启动机制默认设置更改为posix_spawn

基本上在Java 11中,Linux用于启动进程,但到Java 13,它现在使用.vforkposix_spawn

posix_spawn实际上需要一个名为 的程序,该程序位于 .在我的情况下,这存在,但它没有执行权限,这是因为我用来构建一个只有我需要的系统模块的jre,但我在Windows(我的主要开发环境)上创建它。jspawnhelperjre/libjlink

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执行权限,当我部署应用程序时,我对其中的可执行文件设置了执行权限,但不知道其中有任何可执行文件。更改 jspawnhelper 上的权限以执行可以解决此问题。jre/binjre/lib

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

-Djdk.lang.Process.launchMechanism=vfork

答案 2

推荐