Note: this is the CSR for the *Deprecation* of the VFORK mode in JDK 25. A separate CSR exists for its removal in JDK 26 (JDK-8357090)
Summary
-------
The VFORK launch mechanism is very dangerous. It can lead to spurious, very hard-to-diagnose errors in the parent process JVM. It should therefore be removed.
Problem
-------
On Linux, we historically supported three different ways to spawn off a child process via Runtime.exec() and friends:
A) `fork` + `exec` (FORK)
B) `vfork` + `exec` (VFORK)
C) `posix_spawn` + `jspawnhelper` + additional exec (POSIX_SPAWN)
These mechanisms can be chosen by the customer via `-Djdk.lang.Process.launchMechanism=<mode>`.
Between `fork`/`vfork`/`posix_spawn` and `exec` the forked child process runs preparatory code (closing file descriptors etc).
The VFORK mode (B) is dangerous. In the time window between `vfork` and `exec` the child process runs on the memory image of the parent process. It may accidentally damage or kill the parent process. This can happen in many ways, for example by programming error (very easily done, since almost nobody is aware of this danger) but also by things that are outside the control of the programmer, e.g. certain asynchronous signals. See this mail from 2018 [1] describing some real-world cases.
An additional problem is that these errors will look like random crashes or even just sudden deaths of the parent JVM (no hs-err file). So they will mostly not be attributed to `vfork`. Due to a lack of information, these issues are likely very underreported, so they could be more prevalent than we know.
For these reasons we decided to support `posix_spawn` on Linux [2] and use it by default [3]; both changes happened with JDK 13.
But this still leaves the dangerous VFORK mode around; it can be manually enabled with `-Djdk.lang.Process.launchMechanism=VFORK`.
Solution
--------
We propose to deprecate the VFORK mechanism. If a user specifies `-Djdk.lang.Process.launchMechanism=VFORK`, we should write a clear warning message and recommend either removing this switch or using FORK if the user has problems with posix_spawn.
In JDK 25, the VFORK mode will continue to function.
Compatibility Risk
------------------
The risk is very low.
Since JDK 13 (2019) we are using posix_spawn as the default. Installations that manually set `Djdk.lang.Process.launchMechanism=VFORK` will now get a warning message that may trip off automated scripts. According to GitHub, this may affect a small number of Maven build scripts.
Specification
-------------
```
diff --git a/src/java.base/unix/classes/java/lang/ProcessImpl.java b/src/java.base/unix/classes/java/lang/ProcessImpl.java
index 7b5d27f1cc161..505bf9215af3a 100644
--- a/src/java.base/unix/classes/java/lang/ProcessImpl.java
+++ b/src/java.base/unix/classes/java/lang/ProcessImpl.java
@@ -100,16 +100,24 @@ private static LaunchMechanism launchMechanism() {
// Should be value of a LaunchMechanism enum
LaunchMechanism lm = LaunchMechanism.valueOf(s.toUpperCase(Locale.ROOT));
switch (OperatingSystem.current()) {
- case LINUX:
- return lm; // All options are valid for Linux
+ case LINUX: {
+ // All options are valid for Linux, but VFORK is deprecated and results
+ // in a warning
+ if (lm == LaunchMechanism.VFORK) {
+ System.err.println("VFORK MODE DEPRECATED");
+ System.err.println("The VFORK launch mechanism has been deprecated for being dangerous.\n" +
+ "It will be removed in a future java version. Either remove the\n" +
+ "jdk.lang.Process.launchMechanism property (preferred) or use FORK mode\n" +
+ "instead (-Djdk.lang.Process.launchMechanism=FORK).");
+ }
+ return lm;
+ }
case AIX:
case MACOS:
if (lm != LaunchMechanism.VFORK) {
return lm; // All but VFORK are valid
}
break;
- case WINDOWS:
- // fall through to throw to Error
}
} catch (IllegalArgumentException e) {
}
```
Links
-------
- [1] https://mail.openjdk.org/pipermail/core-libs-dev/2018-September/055333.html
- [2] https://bugs.openjdk.org/browse/JDK-8218805
- [3] https://bugs.openjdk.org/browse/JDK-8213192