我的程序将加密的产品密钥数据保存到具有java.util.Preferences类的计算机(系统首选项,而不是用户).问题是,在Windows和Linux上(尚未在OSX上测试,但它可能是相同的),如果我不使用sudo或具有管理员权限运行程序,它会在尝试读取时发出异常或警告或保存数据.
显然要求用户使用Admin权限运行程序是不切实际的.最理想的是,我希望操作系统向用户请求许可.
这是非常愚蠢的,并且消除了一半的目的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.
Run Code Online (Sandbox Code Playgroud)
当我尝试写入节点时会发生这种情况:
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.
Run Code Online (Sandbox Code Playgroud)
pet*_*erh 42
不幸的是,你在这里得到的大部分答案都是错误的...至少是轻微的.从某种意义上说,症状正在得到治疗,而不是原因.
让我们回顾一下.Java Preferences有两个"树":用户树和系统树.您可以将自己的后端编写到Java Preferences(称为后备存储),但开发人员很少,因此您最终得到了JDK的默认后备存储.在Windows平台上,这意味着Win注册表,更具体地说:
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.
Run Code Online (Sandbox Code Playgroud)
那么发生了什么?我给你错误的建议了吗?并不是的.跟我在一起.
深入了解JDK源代码,您将看到0x80000002表示HKLM,即Win Registry中不应触及的位置.您的代码从不引用系统树,但您仍然看到此警告!?? (此时你必须把所有的头发都撕掉......就像我做的那样)
嗯,这是真正存在JDK错误的罕见情况之一.你可以在这个答案中阅读更多关于它的内容,我鼓励你阅读,如果你对为什么在JDK中多年未检测到细微的bug感兴趣.该错误自JDK 1.4以来就已存在,但最近才被修复,尚未向JDK 8移植.
或者,您可以尝试以编程方式忽略警告.它来自JDK的Platform Logger,所以这样的东西应该可以工作,虽然我自己没有尝试过:
sun.util.logging.PlatformLogger platformLogger = PlatformLogger.getLogger("java.util.prefs");
platformLogger.setLevel(PlatformLogger.Level.OFF);
Run Code Online (Sandbox Code Playgroud)kue*_*000 11
可以更改注册表项的访问权限.如果您允许HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Prefs每个人拥有完全访问权限
,那么每个人都会看到相同的首选项,并且每个人都可以在全局范围内进行更改.我知道这不是客户安装的软件的解决方案,但它可能对某人有用.