13

我有一个 Java 应用程序,它通过以下方式读取Preferences

Preferences prefs = Preferences.userNodeForPackage(MyClass.class);
prefs.get((String)key, "");

在新的 Windows 8 机器上,这失败了:

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

错误代码 5 是拒绝访问

我找不到任何我做错的事情。Google 和 SO 搜索给出的旧结果仅与错误使用的 Windows Vista/7 相关systemRoot如何使用 Java 编写系统首选项?可以调用 UAC 吗?)。

可以通过创建 HKLM/Software/JavaSoft/Prefs 并将权限设置为 HKLM/Software/JavaSoft 来“治愈”该错误,如此处所述Java: java.util.Preferences Failing但这不是我可以要求我的用户在安装程序时做的事情。

所以我正在寻找更好的解决方案。我最后的努力是简单地写入文件,但我想避免这种情况。这似乎也与我试图在不使用 Windows 注册表的情况下使用 XML 中的 Java 首选项有关,但我看到了与注册表相关的消息,但它在没有答案的情况下被否决。

目前我怀疑是 Win8 JVM 错误...

问题

  • 有谁知道不涉及写入文件的解决方案?
  • 为什么相同的代码在 Windows 7 中运行良好,但在 Windows 8 中却惨遭失败?
4

1 回答 1

13

我最近开始注意到同样的警告,并认为这意味着无法写入注册表。但经过仔细检查,我注意到所有首选项都在 HKEY_CURRENT_USER 中成功更新。所以我很好奇为什么我会看到这个警告。

原来罪魁祸首就是这个静态成员变量:WindowsPreferences.systemRoot

看起来Java试图初始化 WindowsPreferences.systemRoot 以防程序稍后使用它,如果程序没有以管理员身份运行,初始化显然会失败。

由于您使用的是 Preferences.userNodeForPackage(),因此您永远不需要 systemRoot,因此您可以放心地忽略该警告。

当然,这是一种可怕的做法,Java 在没有请求时尝试初始化 systemRoot。

更新:我在各种 Java 版本中测试了这个问题,并得出结论,这个 bug 是在 Java 1.7.0_21 中引入的。它在 Java 1.7.0_17 中运行良好,仅仅是因为该版本的安装程序会在注册表中创建“Pref”文件夹!当然,即使在那个版本中,如果您要从注册表中删除“Pref”,它也会停止工作,所以这对于 Oracle 来说是一个愚蠢的解决方案。我将填写一份错误报告。

更新 2:警告消息不是错误。这似乎是预期的行为:http ://bugs.java.com/bugdatabase/view_bug.do?bug_id=6809488

于 2013-09-16T18:39:14.773 回答