16

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

Paul Taylor
  • 13,411
  • 42
  • 184
  • 351
  • 1
    are you sure the same code was working with Java-11? – Naman Apr 19 '20 at 09:45
  • @Naman I think so, Im 100% sure working in Java 9 because that has beein production for 6months, I then moved upto Java 11 to fix a issue and never saw these fpcalc errors so I think it was fine, but because Java 11 did not fix original issue I am now trying Java 14, this does fix original issue, but now I am seeing the new issue reported here ! – Paul Taylor Apr 19 '20 at 10:04
  • Not aware of the differences amongst the JDK you've mentioned in these terms. But, is the file read-protected by any means? Assuming the privileges of the user executing the program are the same across JDKs. – Naman Apr 19 '20 at 10:14
  • @Naman I have just rebuilt it to use Java 11 (not Java 14) and reran the same code on same machine and same file and now it is working fine, the only difference is if using jre11 works, if using jre14 doesnt work – Paul Taylor Apr 20 '20 at 11:00

1 Answers1

21

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
Paul Taylor
  • 13,411
  • 42
  • 184
  • 351