Hi, I have a data point to share on the compatibility impact of JDK-8325621 (Improve jspawnhelper version checks), which was backported to earlier release trains.
As a result of that change, doing an in-place upgrade from 22.0.1 to 22.0.2 breaks long-running Java applications that create subprocesses. This is an expected consequence of the change, which adds version checks to jspawnhelper to detect if a JVM is updated in-place to a version with an incompatible jspawnhelper. I'm curious if the list has suggestions on the best way to mitigate the compatibility impact. One possibility is that replacing a JVM in-place for a running process should never happen, and installers should use new directories, or ensure any long-running Java processes are shut down during the upgrade. Is that considered a best practice? Here's a demo of the issue I saw: $ cat T.java public class T { public static void main(String[] args) throws Exception { while (true) { Thread.sleep(1000); System.err.println(Runtime.version()); ProcessBuilder pb = new ProcessBuilder("/usr/bin/date"); pb.redirectError(ProcessBuilder.Redirect.INHERIT); pb.redirectOutput(ProcessBuilder.Redirect.INHERIT); pb.start(); } } } $ ./jdk-22.0.1/bin/java -fullversion openjdk full version "22.0.1+8-16" $ ./jdk-22.0.2/bin/java -fullversion openjdk full version "22.0.2+9-70" $ javac T.java $ rsync -a jdk-22.0.1/ jdk/ $ ./jdk/bin/java T & $ rsync -a jdk-22.0.2/ jdk/ ... jspawnhelper version 22.0.2+9-70 This command is not for general use and should only be run as the result of a call to ProcessBuilder.start() or Runtime.exec() in a java application Exception in thread "main" java.io.IOException: Cannot run program "/usr/bin/date": error=0, Failed to exec spawn helper: pid: 3740946, exit value: 1 at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1170) at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1089) at T.main(T.java:12) Caused by: java.io.IOException: error=0, Failed to exec spawn helper: pid: 3740946, exit value: 1 at java.base/java.lang.ProcessImpl.forkAndExec(Native Method) at java.base/java.lang.ProcessImpl.<init>(ProcessImpl.java:295) at java.base/java.lang.ProcessImpl.start(ProcessImpl.java:225) at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1126) ... 2 more