Issue
What is the exact difference between JDK_JAVA_OPTIONS and href="https://docs.oracle.com/en/java/javase/11/troubleshoot/environment-variables-and-system-properties.html#GUID-BE6E7B7F-A4BE-45C0-9078-AA8A66754B97" rel="noreferrer">JAVA_TOOL_OPTIONS when using Java 11?
I'm using a tiny test program:
public class Foo {
public static final void main(String[] args) {
System.out.println("arg: " + System.getProperty("arg"));
}
}
The two environment variables seem to do the same, but the output is slightly different. That makes me believe they might have different use cases:
$ JDK_JAVA_OPTIONS="-Darg=jdk" java Foo
NOTE: Picked up JDK_JAVA_OPTIONS: -Darg
arg: jdk
$ JAVA_TOOL_OPTIONS="-Darg=tool" java Foo
Picked up JAVA_TOOL_OPTIONS: -Darg
arg: tool
$ JDK_JAVA_OPTIONS="illegalArg" java Foo
NOTE: Picked up JDK_JAVA_OPTIONS: illegalArg
Error: Cannot specify main class in environment variable JDK_JAVA_OPTIONS
$ JAVA_TOOL_OPTIONS="illegalArg" java Foo
Picked up JAVA_TOOL_OPTIONS: illegalArg
Unrecognized option: illegalArg
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.
It seems like JDK_JAVA_OPTIONS
have precedence over JAVA_TOOL_OPTIONS
:
$ JDK_JAVA_OPTIONS="-Darg=jdk" JAVA_TOOL_OPTIONS="-Darg=tool" java Foo
NOTE: Picked up JDK_JAVA_OPTIONS: -Darg=jdk
Picked up JAVA_TOOL_OPTIONS: -Darg=tool
arg: jdk
But ultimately the command line wins:
$ JDK_JAVA_OPTIONS="-Darg=jdk" JAVA_TOOL_OPTIONS="-Darg=tool" java -Darg=cmd Foo
NOTE: Picked up JDK_JAVA_OPTIONS: -Darg=jdk
Picked up JAVA_TOOL_OPTIONS: -Darg=tool
arg: cmd
When building, though, only JAVA_TOOL_OPTIONS
is read:
$ JDK_JAVA_OPTIONS="-Darg=jdk" JAVA_TOOL_OPTIONS="-Darg=tool" javac Foo.java
Picked up JAVA_TOOL_OPTIONS: -Darg=tool
I'm currently using AdoptOpenJDK 11 build 28.
Solution
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.
Answered By - Stephen C
Answer Checked By - Clifford M. (JavaFixing Volunteer)