从/到 Java 首选项的读取和写入在新的 Windows 8 上失败,

2022-09-04 21:27:20

我有一个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相关的旧结果,其中一个人错误地使用了(我如何用Java编写系统偏好设置?我可以调用 UAC 吗?systemRoot

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

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

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

问题

  • 有没有人知道不涉及写入文件的解决方案?
  • 为什么相同的代码在Windows 7中工作得很好,但在Windows 8中却失败了?

答案 1

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

事实证明,罪魁祸首是这个静态成员变量:WindowsPreferences.systemRoot。

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

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

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

更新:我在各种Java版本中测试了这个问题,并得出结论,这个错误是在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


答案 2

推荐