我的程序将保存加密的产品密钥数据传输到计算机与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.
不幸的是大多数,你来到这里的答案是错的......至少咯。在这个意义上,症状正在接受治疗,而不是原因。
让我们来回顾一下。 Java偏好有两个“树”:在user tree和system tree。您可以编写自己的后端Java偏好(所谓的后备存储),但开发者很少这样做,所以你最终的JDK的默认后备存储。在Windows平台上,这意味着胜利登记,更具体:
HKEY_CURRENT_USER\Software\JavaSoft\Prefs
(操作系统用户可以随时在这里写访问)HKEY_LOCAL_MACHINE\Software\JavaSoft\Prefs
(仅管理员PRIVS操作系统用户对这里有写权限)总结:只要您的代码不会尝试使用系统树,你应该罚款,不应需要惹在操作系统级别分配权限。该系统树是为与用户树“在主机上的所有用户”是指为特定的登录用户。在你的情况,我相信你可以与用户树足够了,所以这是真正的解决方案。不要去使用权限搞乱,以管理员身份运行,并没有什么。
....但还有更多。假设你的代码故意不接触Java首系统树,如指示。然后,您还是会看到在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,即在不应该触及赢注册表中的位置。你的代码永远不会引用系统树,但你仍然可以看到这样的警告!?? (此时你必须剥去所有你的头发......像我一样)
那么,这是少有的场合,真的有JDK bug之一。您可以通过我读this answer更多关于它,我鼓励你,如果你有兴趣,为什么微妙的错误不会被检测出来的JDK多年阅读。因为JDK 1.4的bug曾经存在,但直到最近才得到修复,并没有回迁到JDK 8。
sun.util.logging.PlatformLogger platformLogger = PlatformLogger.getLogger("java.util.prefs");
platformLogger.setLevel(PlatformLogger.Level.OFF);
对我来说,解决办法并不明显 - 这是从Oracle更新我的密码安全罐子,因为它似乎是一个关键的长度限制(我不相信这是相关的,直到我尝试了)。
下载包含说明和解释:
由于进口一些国家管制的限制,即在Java运行时环境,或JRE(TM)捆绑在一起的JCE策略文件的版本,8环境让“强”,但要使用有限的加密。这个下载包(一个包括本README文件),提供了包含对加密强度没有限制的“无限力量”的政策文件。
这显然适用于注册表项太多
转到您的注册表和下JavaSoft\Prefs\myapp
创建HKEY_LOCAL_MACHINE-->SOFTWARE
创建密钥名称为偏好设置,并在创建一个子键的myapp,这将解决这个问题。
这link是对我工作:
解决这个问题周围的工作就是登录为administrator
并创建关键HKEY_LOCAL_MACHINE\Software\JavaSoft\Prefs
它可以更改注册表项的访问权限。如果允许完全访问权限HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Prefs
给大家,每个人都会看到相同的偏好组,每个人都将能够在全球范围更改。我知道,这不是由客户安装的软件解决方案,但它可能是使用了别人的。
修改基于反馈的答案。该解决方案可能是矫枉过正,但...
特别是与Windows 7,JVM已经默认情况下不写入到Windows注册表其中用于java.util.prefs.Preferences中的后备存储位于MS-Windows下的权限。
当执行要么ReverseXSL变压器,甚至正则表达式测试程序,我们可以得到这样的错误:在根0x80000002无法打开/创建首选项根节点SOFTWARE \ JavaSoft的\偏好设置。视窗RegCreateKeyEx
这并不阻止注册许可证。这并不妨碍在自由软件模式下执行转换软件。
固定问题仅仅是授予必要的权限,以股权注册表根密钥的问题。
REGEDIT.EXE以管理员身份运行器(regedit.exe位于C:\ Windows操作系统的系统根目录)。转到项HKEY_LOCAL_MACHINE \ SOFTWARE \ JavaSoft的\偏好设置。右键点击设置权限。检查标记为需要执行reverseXSL软件用户(一个或多个)的完全控制复选框。
只要运行该应用程序作为管理员,或使用Eclipse,以管理员身份运行日食。
The Answer by peterh已经详细阐述了背景,但我正在寻找一个修复,并找到了!
既然你不能碰PlatformLogger本身,你要作废的消息:
// get rid of the bugged Preferences warning
PrintStream err = System.err;
System.setErr(new PrintStream(new OutputStream() {
public void write(int b) {}
}));
Preferences PREFS = Preferences.userNodeForPackage(Settings.class);
System.setErr(err);
这样,恼人的警告消失不留任何痕迹。请注意,您只需要在您所引用的偏好API的程序中的第一个时间点来做到这一点。
这终于被修补,2019年1月,在Java SE的开发工具包8u202。
这是补丁集更新(PSU),而不是在重要补丁更新(CPU),8u201。所不同的解释here。 (页面使用Java 7作为一个例子,但它横跨得到点)。
下载可以发现下“的Java SE开发工具包8”页面上较低。 (https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html)
解决方法是运行JMeter的以管理员身份,它会创建注册表项,那么你可以重新启动的JMeter作为一个普通用户,你会不会有警告anymore.JMeter official site - changes