首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Java: java.util.Preferences失败

Java: java.util.Preferences失败
EN

Stack Overflow用户
提问于 2011-03-19 00:17:01
回答 11查看 90.1K关注 0票数 66

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

显然,要求用户以管理员权限运行该程序是不切实际的。最理想的情况是,我希望操作系统向用户询问权限。

这是非常愚蠢的,并且消除了Preferences的一半目的。如何解决这个问题?

这里总结了我需要什么:我需要我的程序请求操作系统的许可来保存系统设置。

以下是错误信息

下面是当我尝试读取一个节点(因为该节点不存在)时出现的错误:

代码语言:javascript
复制
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.

这就是我尝试写一个节点时发生的事情:

代码语言:javascript
复制
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.
EN

回答 11

Stack Overflow用户

回答已采纳

发布于 2017-02-05 16:49:04

不幸的是,你在这里得到的大多数答案都是错误的。至少有一点。从某种意义上说,正在治疗的是症状,而不是原因。

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

  • 用户树写入HKEY_CURRENT_USER\Software\JavaSoft\Prefs (此处OS用户始终具有写入权限)
  • 系统树写入HKEY_LOCAL_MACHINE\Software\JavaSoft\Prefs (此处仅具有管理员权限的OS用户具有写入权限)

总而言之:只要您的代码不尝试使用系统树,您就应该很好,并且不需要在操作系统级别分配权限。系统树用于“主机上的所有用户”,而用户树用于特定的登录用户。在您的情况下,我相信您可以使用用户树,所以这就是您的解决方案。不要搞乱特权,以管理员身份运行等等。

……但还有更多。假设您的代码故意不按照说明接触Java首选项系统树。然后,您仍将在Windows上看到以下警告:

代码语言:javascript
复制
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注册表中不应被触及的位置。您的代码从未引用系统树,但您仍然看到此警告!??(在这一点上,你一定是把头发都扯出来了……就像我做的那样)

嗯,这是真正有JDK bug的罕见情况之一。您可以在我的this answer中阅读更多关于它的内容,如果您对为什么JDK中的细微错误可能多年未被检测到感兴趣,我鼓励您阅读它。这个bug从JDK 1.4开始就存在了,但直到最近才被修复,还没有回传到JDK 8(更新:修复现在已经回传到JDK的8u192版本)

最好的建议

  • 确保您的代码只引用用户树,而不是系统树。操作系统需要所有类型的privs才能写入系统范围的位置,这才是公平的。如果您真的需要写入这样的位置,那么除了分配权限、以管理员身份执行或不以管理员身份执行之类的操作之外,实际上没有其他解决方案。

  • 忽略该警告。一旦您使用Java8更新192或更高版本,它就会消失。可以安全地忽略该警告。

  • Alternatively您可以尝试以编程方式使警告静默。它来自JDK的Platform Logger,所以这样的东西应该可以工作,尽管我自己还没有尝试过:

platformLogger.setLevel(PlatformLogger.Level.OFF);;sun.util.logging.PlatformLogger platformLogger =PlatformLogger.getLogger(“java.util.prefs”)

票数 47
EN

Stack Overflow用户

发布于 2013-03-29 14:54:26

link适用于我:

解决方法是以administrator身份登录并创建密钥HKEY_LOCAL_MACHINE\Software\JavaSoft\Prefs

票数 42
EN

Stack Overflow用户

发布于 2011-08-23 15:53:34

可以更改注册表项的访问权限。如果您允许每个人拥有对HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Prefs的完全访问权限,每个人都将看到相同的首选项集,并且每个人都可以在全局范围内更改它们。我知道这不是针对客户安装的软件的解决方案,但它可能对某些人有用。

票数 11
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5354838

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档