当使用Java 11时,JDK_JAVA_OPTIONS和JAVA_TOOL_OPTIONS有什么区别?

43

当使用Java 11时,JDK_JAVA_OPTIONSJAVA_TOOL_OPTIONS之间的确切区别是什么?

我正在使用一个小测试程序:

public class Foo {
  public static final void main(String[] args) {
    System.out.println("arg: " + System.getProperty("arg"));
  }
}

这两个环境变量看起来很相似,但输出略有不同。这让我相信它们可能具有不同的用途:

$ 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.

看起来JDK_JAVA_OPTIONS的优先级高于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

但最终命令行获胜:

$ 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

然而,在构建时只会读取JAVA_TOOL_OPTIONS

$ JDK_JAVA_OPTIONS="-Darg=jdk" JAVA_TOOL_OPTIONS="-Darg=tool" javac Foo.java
Picked up JAVA_TOOL_OPTIONS: -Darg=tool

我目前使用的是AdoptOpenJDK 11版本28。


它们不是环境变量,可以按照您的意愿定义吗? - Naman
@nullpointer 我不确定你的意思是什么?两者都可以成功地用于为java设置选项,但它们似乎实现略有不同(基于java命令的输出)。 - neu242
2
一些相关的内容:https://dev59.com/114c5IYBdhLWcg3wFm44,https://bugs.openjdk.java.net/browse/JDK-8185446 - Henry
1
@Henry 谢谢,我已经看过了。但是它们并没有回答我的问题... - neu242
2个回答

39
  • JDK_JAVA_OPTIONS 只被 java 启动器所识别,因此请使用它来设置你只希望应用于Java启动命令的选项。该变量也是JDK 9+版本中新增的,早期版本将忽略它。因此,在从旧版本迁移到9+版本时非常有用。
  • JAVA_TOOL_OPTIONS 也被其他Java工具(如 jarjavac)所使用,因此应该用于你想要应用到所有这些Java工具上的标志(并且这些标志有效)。

17

根据 @gjoranv 的回答,这两个变量之间的功能差异得以解释。

我认为输出结果的不同源于以下原因:

  1. 这两个变量似乎在启动过程中的不同点实现。

  2. JDK_JAVA_OPTIONS 文档如下所示:

    为了避免 JDK_JAVA_OPTIONS 行为被滥用,禁止在环境变量中使用指定主类(如 -jar)或导致 Java 启动器在不执行主类的情况下退出的选项(如 -h)。如果任何这些选项出现在环境变量中,则启动器将停止并显示错误消息。

    该行:

     Error: Cannot specify main class in environment variable JDK_JAVA_OPTIONS
    

    这是一个错误信息,提醒用户存在通过该变量进行破坏的潜在尝试。

    我认为JDK_JAVA_OPTIONS具有优先权,部分原因是相同的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接