Java的:java.util.Preferences失败

问题描述 投票:63回答:11

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

显然,需要用户用管理员权限运行该程序将是不切实际的。理想情况下,我想操作系统要求允许用户。

这是相当愚蠢的,并删除Preferences一半的目的。这怎么能解决?

这里有一个总结我需要什么:我需要我的程序从操作系统请求允许保存系统设置。


Here is the error information

这里的错误时,当我尝试读取一个节点(因为节点不存在):

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 preferences
11个回答
42
投票

不幸的是大多数,你来到这里的答案是错的......至少咯。在这个意义上,症状正在接受治疗,而不是原因。

让我们来回顾一下。 Java偏好有两个“树”:在user treesystem 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。

最好的建议

  • 确保你的代码只引用用户树,而不是系统树。该操作系统需要各种PRIVS的为你写一个全系统的位置是唯一公平的。如果你真的需要写入到这样一个位置,然后确实没有其他的解决办法不是分配PRIVS,以管理员身份运行或什么不是。
  • 忽略警告。一旦你在Java的9时或甲骨文决定反向移植bug修复到Java 8警告可以放心地忽略它会消失。
  • 另外,您可以尝试以编程忽略警告。它来自于JDK的平台记录器,所以这样的事情应该工作,虽然我还没有尝试过自己: sun.util.logging.PlatformLogger platformLogger = PlatformLogger.getLogger("java.util.prefs"); platformLogger.setLevel(PlatformLogger.Level.OFF);

0
投票

对我来说,解决办法并不明显 - 这是从Oracle更新我的密码安全罐子,因为它似乎是一个关键的长度限制(我不相信这是相关的,直到我尝试了)。

Download from Oracle website

下载包含说明和解释:

由于进口一些国家管制的限制,即在Java运行时环境,或JRE(TM)捆绑在一起的JCE策略文件的版本,8环境让“强”,但要使用有限的加密。这个下载包(一个包括本README文件),提供了包含对加密强度没有限制的“无限力量”的政策文件。

这显然适用于注册表项太多


-1
投票

转到您的注册表和下JavaSoft\Prefs\myapp创建HKEY_LOCAL_MACHINE-->SOFTWARE

创建密钥名称为偏好设置,并在创建一个子键的myapp,这将解决这个问题。


42
投票

link是对我工作:

解决这个问题周围的工作就是登录为administrator并创建关键HKEY_LOCAL_MACHINE\Software\JavaSoft\Prefs


11
投票

它可以更改注册表项的访问权限。如果允许完全访问权限HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Prefs给大家,每个人都会看到相同的偏好组,每个人都将能够在全球范围更改。我知道,这不是由客户安装的软件解决方案,但它可能是使用了别人的。


5
投票

修改基于反馈的答案。该解决方案可能是矫枉过正,但...

  • 我建议你改变你的店写入一个文件,而不是注册表(example
  • 很多基于java的产品船舶用自己的JVM。他们这样做,使他们可以用自定义策略文件(这将在你的情况写信给一个共同的位置需要)运行和支持问题保存(如过时/未经JVM的使用)

3
投票

特别是与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软件用户(一个或多个)的完全控制复选框。


1
投票

只要运行该应用程序作为管理员,或使用Eclipse,以管理员身份运行日食。


1
投票

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的程序中的第一个时间点来做到这一点。


1
投票

这终于被修补,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


0
投票

解决方法是运行JMeter的以管理员​​身份,它会创建注册表项,那么你可以重新启动的JMeter作为一个普通用户,你会不会有警告anymore.JMeter official site - changes

© www.soinside.com 2019 - 2024. All rights reserved.