Groovy Shell警告“无法打开/创建Prefs根节点..”

我尝试在Windows 8上打开Groovy shell(groovysh),并获得以下输出:

java.util.prefs.WindowsPreferences <init>
WARNING: Could not open/create prefs root node Software\JavaSoft\Prefs
at root 0x80000002. Windows RegCreateKeyEx(...) returned error code 5.

打印上述消息后,shell按预期启动。

157203 次浏览

我可以通过手动创建以下注册表项来解决此问题:

HKEY_LOCAL_MACHINE\Software\JavaSoft\Prefs

丹尼斯的回答是正确的。然而,我想以更详细的方式解释解决方案(对于Windows用户):

  1. 进入“开始”菜单,在搜索栏中键入regedit
  2. 导航到路径HKEY_LOCAL_MACHINE\Software\JavaSoft(Windows 10现在似乎有这个:HKEY_LOCAL_MACHINE\Software\WOW6432Node\JavaSoft
  3. 右键单击JavaSoft文件夹,然后单击New->Key
  4. 将新密钥_命名为ABC_0,一切正常。

或者,保存并执行包含以下内容的*.reg文件:

Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\Software\JavaSoft\Prefs]

如果有人试图在64位版本的Windows上解决此问题,您可能需要创建以下密钥:

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\JavaSoft\Prefs

在64位Windows 8上启动Apache JMeter时遇到类似问题:

[]apache-jmeter-2.13\bin>jmeter
java.util.prefs.WindowsPreferences <init>
WARNING: Could not open/create prefs root node Software\JavaSoft\Prefs     at root 0x80000002. Windows RegCreateKeyEx(...) returned error code 5.

成功使用了Dennis Traub解决方案,以及Mkorsch的解释。或者,您可以创建一个扩展名为“ reg ”的文件,并在其中写入以下内容:

Windows Registry Editor Version 5.00


[HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Prefs]

...那就执行它。

我收到了以下消息:

Could not open/create prefs root node Software\JavaSoft\Prefs at root 0x80000002

在创建其中一个注册表项后,它就消失了,我的注册表项是64位的,所以我只试了一下。

32 bit Windows
HKEY_LOCAL_MACHINE\Software\JavaSoft\Prefs


64 bit Windows
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\JavaSoft\Prefs

问题是简单的控制台不能编辑注册表。无需手动编辑注册表,只需使用管理权限启动groovysh一次即可。所有后续启动工作没有错误。

这发生在我身上。

显然,这是因为Java没有创建注册表项的权限。

请参阅:Java:Java.util.Preferences失败

这实际上是一个JDK错误。在过去的几年里,它已经被报道过多次,但只有在8139507中,它才最终被Oracle认真对待。

问题出在WindowsPreferences.java的JDK源代码中。在该类中,ABC_1_节点和ABC_2_节点都被声明为静态,如下所示:

/**
* 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安装程序将为您创建ABC_0_注册表项,这将有效地隐藏该错误。另一方面,您从来没有真正被要求运行安装程序以便在您的机器上安装JRE,或者至少这不是Sun/Oracle的意图。如您所知,Oracle多年来一直以.tar.gz格式分发用于Windows的JRE.

问题确实是缺少注册键。可以手动创建

或者

通过以管理员身份运行一次程序,可以创建自动地。这将为程序提供所需的权限,并且当它正常运行时,它仍然可以正常工作。