这实际上是一个 JDK 错误。这些年被报道了好几次,但只有8139507才最终被甲骨文认真对待。
问题出在WindowsPreferences.java
. 在这个类中,两个节点userRoot
都systemRoot
被声明为静态的,如下所示:
/**
* User root node.
*/
static final Preferences userRoot =
new WindowsPreferences(USER_ROOT_NATIVE_HANDLE, WINDOWS_ROOT_PATH);
/**
* System root node.
*/
static final Preferences systemRoot =
new WindowsPreferences(SYSTEM_ROOT_NATIVE_HANDLE, WINDOWS_ROOT_PATH);
这意味着第一次引用该类时,两个静态变量都将被启动,并且如果HKEY_LOCAL_MACHINE\Software\JavaSoft\Prefs
(=系统树)的注册表项尚不存在,则将尝试创建它。
因此,即使用户在自己的代码中采取了一切预防措施并且从未接触或引用系统树,那么 JVM 实际上仍会尝试实例化systemRoot
,从而导致警告。这是一个有趣的微妙错误。
2016 年 6 月对 JDK 源进行了修复,它是 Java9 及更高版本的一部分。在u202 中还有一个Java8的后向端口。
您看到的实际上是来自 JDK 内部记录器的警告。这也不例外。我相信可以安全地忽略该警告....除非用户代码确实需要系统首选项,但这种情况很少见。
奖金信息
该错误不会在 Java 1.7.21 之前的版本中显示出来,因为在此之前 JRE 安装程序会HKEY_LOCAL_MACHINE\Software\JavaSoft\Prefs
为您创建注册表项,这将有效地隐藏该错误。另一方面,您从未真正需要运行安装程序才能在您的机器上安装 JRE,或者至少这不是 Sun/Oracle 的意图。您可能知道,Oracle 多年来一直以.tar.gz
格式分发适用于 Windows 的 JRE。