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

Posted

技术标签:

【中文标题】Groovy Shell 警告“无法打开/创建首选项根节点...”【英文标题】:Groovy Shell warning "Could not open/create prefs root node ..." 【发布时间】:2013-05-01 22:35:08 【问题描述】:

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

【问题讨论】:

这是由于一个错误:bugs.java.com/bugdatabase/view_bug.do?bug_id=6790382 作为backing store 保存在文件中的首选项应该完全避免这个问题。在某些情况下,依靠最终用户更改他们的abominable registry 并不是一个可行的解决方案。 这是一个已知的 Java 错误,在 WIndows 10 和更新 112 上仍然存在。只需从提升的提示符处运行该程序一次,它就会消失。 【参考方案1】:

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

    进入“开始”菜单并在搜索字段中输入regedit。 导航到路径HKEY_LOCAL_MACHINE\Software\JavaSoft(Windows 10 现在似乎在这里有这个:HKEY_LOCAL_MACHINE\Software\WOW6432Node\JavaSoft) 右键单击JavaSoft文件夹并单击New -> Key 将新密钥命名为 Prefs,一切正常。

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

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

【讨论】:

是否有可能以编程方式执行此操作? 我可以确认如果在 HKEY_CURRENT_USER 下完成它不会起作用。一个更好的问题,为什么基于 Java 的产品会与 Windows 注册表绑定? 消费者应用程序不可能要求用户去修改注册表。为什么Java总是这样实现半解决方案。 我的 Windows 10 安装具有上述两个关键路径,修复我的安装需要将首选项添加到 HKEY_LOCAL_MACHINE\Software\JavaSoft 而不是 HKEY_LOCAL_MACHINE\Software\WOW6432Node\JavaSoft 在 Windows 10 上,Perfs 文件夹的正确位置仍然是 HKEY_LOCAL_MACHINE\Software\JavaSoft【参考方案2】:

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

HKEY_LOCAL_MACHINE\Software\JavaSoft\Prefs

【讨论】:

你介意告诉我确切的过程吗?我主要在 Mac 上工作,但在 Windows 上运行程序时出现此错误,我想知道如何修复它。 我在我们销售的软件上看到了这一点。如果您也有其中一个,那么自动/程序化修复会更好。告诉我的最终用户跳入 regedit 是一个可怕的前景。有没有办法让 Java 在 Windows 8.1 上自动执行此操作(这是我看到错误的唯一平台)。 Windows 10 也发生错误,此修复有效【参考方案3】:

这实际上是一个 JDK 错误。这些年来已经多次报道,但只有在8139507 才最终被甲骨文认真对待。

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

在 2016 年 6 月对 JDK 源代码进行了修复,它是 Java9 及更高版本的一部分。在 u202 中还有一个用于 Java8 的 backport。

您看到的实际上是来自 JDK 内部记录器的警告。这也不例外。我相信可以安全地忽略该警告....除非用户代码确实需要系统首选项,但这种情况很少见。

奖金信息

该错误在 Java 1.7.21 之前的版本中并未出现,因为在此之前 JRE 安装程序会为您创建注册表项 HKEY_LOCAL_MACHINE\Software\JavaSoft\Prefs,这将有效地隐藏该错误。另一方面,您从未真正需要运行安装程序才能在您的机器上安装 JRE,或者至少这不是 Sun/Oracle 的意图。您可能知道,Oracle 多年来一直以 .tar.gz 格式分发适用于 Windows 的 JRE。

【讨论】:

感谢您的深入分析。您提到的Issue 8139507 说该错误已在 JDK 9 中修复。 @realsonic。补充一点:看来甲骨文终于开始向后移植这个修复程序了。它是fixed in 8u202。 (截至 2018 年 9 月 30 日,Java 8 的最新版本是 u181,因此该修复已向后移植,但尚未在任何发布版本中)【参考方案4】:

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

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\JavaSoft\Prefs

【讨论】:

我在 64 位 Windows 7 上使用 64 位 JVM 时遇到此错误,而 Dennis 和 MKorsch 提出的解决方案对我来说效果很好。或许 Wow6432Node 解决方案适用于 64 位 Windows 上的 32 位 JVM。【参考方案5】:

问题是简单的控制台无法编辑注册表。无需手动编辑注册表,只需使用管理权限启动一次groovysh。所有后续启动都正常运行。

【讨论】:

谢谢,我建议其他人试试这个,这是最简单的解决方案:) 最简单的答案,应该在上面。我在执行 JMeter 测试时遇到了这个警告,但是我以管理员身份启动了 jmeter.bat 并且警告消失了。【参考方案6】:

在 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]

...然后执行它。

【讨论】:

【参考方案7】:

我收到以下消息:

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

【讨论】:

【参考方案8】:

这发生在我身上。

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

见:Java: java.util.Preferences Failing

【讨论】:

嗯,更准确地说是因为 JDK 中存在错误。在您的答案中的链接上查看接受的答案。 这并不是一个真正的错误 - 机器范围的设置只允许机器管理员用户使用。使用runas 以本地管理员用户身份运行您的应用程序,它将愉快地在 HKLM 下创建注册表项。 Java 所没有的是一种请求提升权限的机制(即,理想情况下,它会调用 Windows UAC 而不是失败——这是否是普遍的好主意值得怀疑)。【参考方案9】:

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

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

【讨论】:

以上是关于Groovy Shell 警告“无法打开/创建首选项根节点...”的主要内容,如果未能解决你的问题,请参考以下文章

Groovy 执行 shell 命令

如何正确地从 groovy 调用 shell 命令

Groovy:如何定义带有参数的 java callable 并使其可用于 groovy shell?

buildTypes 不能应用于 groovy.lang.Closure

jenkins执行groovy 脚本报错

IntelliJ IDEA创建第一个Groovy工程