Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Just moved from Java 11 to Java 14

The following code is now failing on a linux machine:

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]));                    

with stacktrace

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)

What has changed in Java 14 that would cause this ?

I ran the equivalent code on Windows using java 14 and that did run okay. But I had retried with same code base on this unix machine using both Java 11 and Java 14 and can confirm that Java 11 always works and Java 14 always fails

like image 556
Paul Taylor Avatar asked Apr 19 '20 08:04

Paul Taylor


People also ask

What happens if jspawnhelper cannot exec?

But if the jspawnhelper cannot be exec ()'ed - e.g. because its permissions are forbidding execution - currently, on glibc, we will not get an error. From the outside it looks like the child process quits immediately.

What does the jspawnhelper update do?

It fixes a bug in sub process spawning where, if the spawn method is "posix_spawn", and the jspawnhelper could not be spawned - e.g. because someone copied the jdk somewhere without resetting execute permissions - no exception would be thrown and it would look like the child process just terminated immediately.

What is wrong with posix_spawn ()?

The problem is that the glibc version of posix_spawn () does not report back an error if the exec () step fails. Instead, the child process will just quit with error code 127. Strictly speaking that is no bug since POSIX allows that. But for us this situation is indistinguishable from a user program exiting with 127.

Is it possible to run Java 14 on Java 11?

I ran the equivalent code on Windows using java 14 and that did run okay. But I had retried with same code base on this unix machine using both Java 11 and Java 14 and can confirm that Java 11 always works and Java 14 always fails Show activity on this post.


1 Answers

I have found the issue, I came across these issues on the Openjdk Bugs Database

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

and

Change the Process launch mechanism default on Linux to be posix_spawn

Essentially in Java 11 Linux uses vfork to start processes but by Java 13 it now uses posix_spawn.

posix_spawn actually requires a program called jspawnhelper that is located within jre/lib. In my case this exists but it does not have execute permissions, this is because I use jlink to build a jre that just has the system modules I need, but I create this on Windows (my main dev environment).

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 doesn't understand linux execute permissions, when I deploy my application I set execute permission on the executables that are in jre/bin but didn't know there were any executables in jre/lib. Changing the permissions on jspawnhelper to execute fixes the issue.

An alternative workaround is to add the following java option:

-Djdk.lang.Process.launchMechanism=vfork
like image 118
Paul Taylor Avatar answered Sep 17 '22 15:09

Paul Taylor