What is the exact difference between JDK_JAVA_OPTIONS and JAVA_TOOL_OPTIONS when using Java 11?
They seem to do the same, but the output is slightly different. That makes me believe they might have different use cases:
$ JDK_JAVA_OPTIONS="-Dstuff" java Foo
NOTE: Picked up JDK_JAVA_OPTIONS: -Dstuff
$ JDK_JAVA_OPTIONS="illegalStuff" java Foo
NOTE: Picked up JDK_JAVA_OPTIONS: illegalStuff
Error: Cannot specify main class in environment variable JDK_JAVA_OPTIONS
$ JAVA_TOOL_OPTIONS="-Dstuff" java Foo
Picked up JAVA_TOOL_OPTIONS: -Dstuff
$ JAVA_TOOL_OPTIONS="illegalStuff" java Foo
Picked up JAVA_TOOL_OPTIONS: illegalStuff
Unrecognized option: illegalStuff
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.
I'm using a tiny test program:
public class Yo {
public static final void main(String[] args) {
System.out.println(System.getProperty("stuff"));
}
}
It shows that JDK_JAVA_OPTIONS have precedence over JAVA_TOOL_OPTIONS:
$ JDK_JAVA_OPTIONS="-Dstuff=jdk" JAVA_TOOL_OPTIONS="-Dstuff=tool" java Yo
NOTE: Picked up JDK_JAVA_OPTIONS: -Dstuff=jdk
Picked up JAVA_TOOL_OPTIONS: -Dstuff=tool
jdk
But ultimately the command line wins:
$ JDK_JAVA_OPTIONS="-Dstuff=jdk" JAVA_TOOL_OPTIONS="-Dstuff=tool" java -Dstuff=cmd Yo
NOTE: Picked up JDK_JAVA_OPTIONS: -Dstuff=jdk
Picked up JAVA_TOOL_OPTIONS: -Dstuff=tool
cmd
When building, though, only JAVA_TOOL_OPTIONS is read:
$ JDK_JAVA_OPTIONS="-Dstuff=jdk" JAVA_TOOL_OPTIONS="-Dstuff=tool" javac Yo.java
Picked up JAVA_TOOL_OPTIONS: -Dstuff=tool
I'm currently using AdoptOpenJDK 11 build 28.
解决方案
The functional difference between the two variables is explained by @gjoranv's answer.
The differences in the output I think stem from the following:
The two variables seem to be implemented in different points in the launching process.
The JDK_JAVA_OPTIONS documentation says:
In order to mitigate potential misuse of JDK_JAVA_OPTIONS behavior, options that specify the main class (such as -jar) or cause the java launcher to exit without executing the main class (such as -h) are disallowed in the environment variable. If any of these options appear in the environment variable, the launcher will abort with an error message.
This line:
Error: Cannot specify main class in environment variable JDK_JAVA_OPTIONS
is the error message that warns the user of a potential attempt to do mayhem via that variable.
I think that JDK_JAVA_OPTIONS takes precedence, in part for the same reason.