Java:java.util.Preferences失败

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (45)

我的程序将加密的产品密钥数据与java.util.Preferences类(系统首选项,而不是用户)一起保存到计算机中。问题是,在Windows和Linux上(没有在OSX上测试过,但它可能是相同的),如果我没有sudo使用管理员权限运行程序,它会在尝试读取或发出异常或警告时发出异常或警告保存数据。

显然要求用户以管理员权限运行程序是不切实际的。最好是,我希望操作系统向用户请求许可。

这很愚蠢,并且消除了一半的目的Preferences。这怎么解决?

以下是我需要的摘要:我需要我的程序向操作系统请求许可以保存系统设置。

这是错误信息

以下是我尝试读取节点时的错误(因为节点不存在):

Mar 18, 2011 9:41:15 AM java.util.prefs.WindowsPreferences <init>
WARNING: Could not create windows registry node Software\JavaSoft\Prefs\myapp at root 0x80000002. Windows RegCreateKeyEx(...) returned error code 5.
Mar 18, 2011 9:41:15 AM java.util.prefs.WindowsPreferences WindowsRegOpenKey1
WARNING: Trying to recreate Windows registry node Software\JavaSoft\Prefs\myapp at root 0x80000002.
Mar 18, 2011 9:41:15 AM java.util.prefs.WindowsPreferences openKey
WARNING: Could not open windows registry node Software\JavaSoft\Prefs\myapp at root 0x80000002. Windows RegOpenKey(...) returned error code 2.
Mar 18, 2011 9:41:15 AM java.util.prefs.WindowsPreferences WindowsRegOpenKey1
WARNING: Trying to recreate Windows registry node Software\JavaSoft\Prefs\myapp\subpackage at root 0x80000002.
Mar 18, 2011 9:41:15 AM java.util.prefs.WindowsPreferences openKey
WARNING: Could not open windows registry node Software\JavaSoft\Prefs\myapp\subpackage at root 0x80000002. Windows RegOpenKey(...) returned error code 2.

这是当我尝试写入节点时发生的情况:

Mar 18, 2011 9:43:11 AM java.util.prefs.WindowsPreferences WindowsRegOpenKey1
WARNING: Trying to recreate Windows registry node Software\JavaSoft\Prefs\myapp\subpackage at root 0x80000002.
Mar 18, 2011 9:43:11 AM java.util.prefs.WindowsPreferences openKey
WARNING: Could not open windows registry node Software\JavaSoft\Prefs\myapp\subpackage at root 0x80000002. Windows RegOpenKey(...) returned error code 2.
提问于
用户回答回答于

user tree

不幸的是,你在这里得到的答案大部分都是错误的......至少略微。在症状正在治疗的意义上,而不是原因。

让我们回顾一下。Java首选项有两个“trees”:user treesystem tree。您可以将自己的后端编写到Java首选项(称为后备存储),但很少有开发人员这样做,因此您最终将获得JDK的默认后备存储。在Windows平台上,这意味着Win Registry,更具体地说:

  • 用户树被写入HKEY_CURRENT_USER\Software\JavaSoft\Prefs(操作系统用户总是对这里有写权限)
  • 系统树被写入HKEY_LOCAL_MACHINE\Software\JavaSoft\Prefs(只有一个操作系统的用户具有管理员PRIVS这里有写权限)

总结:只要你的代码不尝试使用系统树,你应该没问题,不应该在操作系统级别上分配权限。系统树意味着“主机上的所有用户”,用户树意味着特定的登录用户。在你的情况下,我相信你可以满足用户树,所以这真的是你的解决方案。不要去搞特权,以管理员身份运行,而不是。

....但还有更多。按照说明,假设您的代码有意不触及Java Preferences系统树。然后,您将仍然看到在Windows这样的警告:

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

那么发生了什么?我给了你错误的建议吗?不是真的。跟我在一起。

潜入JDK源代码中,您将看到0x80000002意味着HKLM,即Win Registry中不应该被触及的地方。你的代码永远不会引用系统树,但你仍然看到这个警告!(在这一点上,你必须把你所有的头发都撕掉......就像我一样)

那么,这是真正存在JDK错误的罕见情况之一。您可以在我的答案中阅读更多关于它的内容,如果您对为什么微软bug会在JDK中未被发现多年感兴趣,我鼓励您阅读。该错误自从JDK 1.4以来一直存在,但最近才被修复,但尚未被移植到JDK 8。

最好的建议

  • 确保你的代码只引用用户树,而不是系统树。操作系统需要各种priv才能写入系统范围,这是公平的。如果你真的需要写入这样的位置,那么真的没有别的解决办法,只能分配priv,以管理员身份执行或不执行。
  • 忽略警告。一旦使用Java 9或Oracle决定将错误修复程序恢复到Java 8时,它就会消失。警告可以安全地忽略。
  • 或者,您可以尝试以编程方式忽略该警告。它来自JDK的平台记录器,所以像这样的东西应该可以工作,尽管我自己并没有尝试过: sun.util.logging.PlatformLogger platformLogger = PlatformLogger.getLogger("java.util.prefs"); platformLogger.setLevel(PlatformLogger.Level.OFF);
用户回答回答于

链接适用于我:

解决问题解决方法是登录administrator并创建密钥HKEY_LOCAL_MACHINE\Software\JavaSoft\Prefs

扫码关注云+社区