在全新的Windows 8系统上,从/向Java首选项读写失败。

13

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

我有一個 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失败但这不是我安装程序时可以要求用户做的事情。

因此,我正在寻找更好的解决方案。我最后的努力是简单地写入文件,但我想避免这样做。这似乎也涉及我正在尝试在不使用Windows注册表的情况下使用XML中的Java Prefences,但我看到一个与注册表相关的消息 ,但它被否决而没有答案。

目前,我怀疑是Win8 JVM的错误…

问题

  • 是否有任何人知道不涉及写文件的解决方案?
  • 为什么相同的代码在Windows 7中完全正常工作但在Windows 8中失败了?
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:警告消息不是bug。这似乎是预期行为:http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6809488


是的,问题是在我的情况下这不是一个警告,而是JVM直接崩溃了。因为它无法创建那个不存在的键,而我也不需要它:/ 但是确实很烦人。 - Emily L.
异常似乎源自我的代码,但即使读取失败,该代码仍然有效... - Emily L.
因此,它不会使您的JVM崩溃。它只是抛出一个异常。异常来自于HardpointType.java文件。我猜测HardpointType尝试从systemNode而不是userNode中读取某些内容。systemNode返回null,这可能是为什么您会收到“未知硬点类型”错误消息的原因。 - Saeid Nourian
你提到了你提交了一个错误报告。有可能提供一个链接吗? - jdknight
1
很不幸,这个错误报告没有被提交成功。Oracle似乎忽略了大部分的错误报告。看起来Netbean的人甚至试图为这个同样的问题提交一个错误报告,但他们也没有成功:https://netbeans.org/bugzilla/show_bug.cgi?id=234894 - Saeid Nourian
显示剩余9条评论

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