Groovy Shell警告:“无法打开/创建首选项根节点…”

195

我尝试在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如预期般启动。


3
这是由于一个漏洞引起的:http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6790382 - Kristof Neirynck
1
将偏好设置保存在文件中作为后备存储,可以完全避免这个问题。有些情况下,依赖最终用户更改他们的可恶的注册表并不是一个可行的解决方案。 - Dave Jarvis
2
这是一个已知的Java漏洞,在Windows 10和更新的112版本中仍然存在。只需从提升的提示符中运行程序一次即可解决。 - david.pfx
9个回答

336

Dennis的答案是正确的。 然而,我想对解决方案进行更详细的说明(适用于Windows用户):

  1. 进入开始菜单,将regedit键入搜索栏。
  2. 导航至路径HKEY_LOCAL_MACHINE\Software\JavaSoft (Windows 10似乎现在在这里:HKEY_LOCAL_MACHINE\Software\WOW6432Node\JavaSoft)
  3. 右键单击JavaSoft文件夹,点击New -> Key
  4. 将新关键字命名为Prefs,然后一切都应该正常工作。

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

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

8
可以通过编程来实现这个吗? - facetoe
13
如果在HKEY_CURRENT_USER下进行,我可以确认它不起作用。一个更好的问题是,为什么一个基于Java的产品要绑定到Windows注册表上? - avgvstvs
5
消费者应用程序不可能要求用户去调整注册表。为什么Java总是实现这样的半解决方案。 - El Mac
16
我的Windows 10安装同时具有上述两个关键路径,修复我的安装需要将“Prefs”添加到HKEY_LOCAL_MACHINE\Software\JavaSoft而不是HKEY_LOCAL_MACHINE\Software\WOW6432Node\JavaSoft。 - gt124
2
只需将失败的应用程序以管理员身份运行一次,它就会自动创建缺失的密钥。无需修改注册表。 - rustyx
显示剩余7条评论

75

我通过手动创建以下注册表键来解决了这个问题:

HKEY_LOCAL_MACHINE\Software\JavaSoft\Prefs

你介意告诉我具体的过程吗?我主要在 Mac 上工作,但是当我在 Windows 上运行我的程序时出现了错误,我想知道如何修复它。 - moomoohk
14
我看到这个问题出现在我们销售的软件中。如果你有自动/程序化的修复方法,那会更好。让我的最终用户跳进注册表编辑器是一个可怕的前景。是否有办法让Java在Windows 8.1上自动处理这个问题(这是我发现错误的唯一平台)? - Brian Knoblauch
错误也会在Windows 10中发生,而这个修复方法有效。 - TriumphST

49

实际上这是一个JDK的bug。多年来曾有多次报告,但直到8139507,Oracle才真正重视此问题。

问题出现在WindowsPreferences.java的JDK源代码中。在这个类中,userRootsystemRoot两个节点都被声明为静态,如下所示:

/**
 * 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,从而导致警告。这是一个有趣的微妙错误。

JDK源代码修复于2016年6月提交,从Java9开始就已经包含在内了。Java8也有一个回退版本,在u202中。

你看到的只是JDK内部记录器的一个警告,不是异常。我相信这个警告可以安全地忽略......除非用户代码确实需要系统首选项,但这种情况很少见。

额外信息

这个错误在Java 1.7.21之前的版本中没有显露出来,因为在那之前JRE安装程序会为您创建注册表键HKEY_LOCAL_MACHINE\Software\JavaSoft\Prefs,从而有效地隐藏了这个错误。另一方面,您实际上并不需要运行安装程序才能在计算机上拥有JRE,或者至少这不是Sun/Oracle的意图。就像你可能知道的那样,Oracle多年来一直以.tar.gz格式分发Windows版JRE。


感谢您进行如此深入的分析。您提到的问题8139507表示该错误已在JDK 9中修复。 - realsonic
3
此外,似乎Oracle终于开始回溯修复这个问题。它已经在8u202中得到修复(截至2018年9月30日,Java 8的最新版本是u181,所以该修复已被回溯但尚未在任何发布版本中)。 - peterh

32

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

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\JavaSoft\Prefs

9
我在64位的Windows 7上使用64位JVM时遇到了这个错误,Dennis和MKorsch提出的解决方案对我非常有效。也许Wow6432Node的解决方案适用于64位Windows上的32位JVM。 - Scott Johnson

8
问题是简单的控制台无法编辑注册表。无需手动编辑注册表,只需以管理员权限启动groovysh一次即可。所有后续的启动都可以正常工作,不会出现错误。

2
谢谢,我建议其他人也尝试一下,这是最简单的解决方案 :) - Aditya T
1
最简单的答案应该放在最上面。我在执行JMeter测试时遇到了这个警告,但是我以管理员身份启动了jmeter.bat一次,警告就消失了。 - K. B.

2

在Windows 8 64位系统上启动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]

...然后执行它。


1
我收到了以下消息:
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

1

更确切地说,这是因为 JDK 中存在错误。请参见您回答中链接上的已接受答案。 - peterh
这并不是一个真正的 bug - 机器范围的设置只允许机器管理员用户。使用 runas 以本地管理员用户身份运行您的应用程序,它将愉快地在 HKLM 下创建注册表键。Java 没有的是请求提升权限的机制(即理想情况下它应该调用 Windows UAC 而不是失败 - 这是否普遍适用还有待商榷)。 - ddimitrov

0
问题确实是缺少注册表键。可以手动创建。
或者,可以通过以管理员身份运行程序来自动创建。这将为程序提供所需的权限,当以正常方式运行时,它仍将正常工作。

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