Java: java.util.Preferences Failing

JavaPreferences

Java Problem Overview


My program saves encrypted product key data to the computer with the java.util.Preferences class (system preferences, not user). The problem is, on both Windows and Linux (haven't tested on OSX, but it's probably the same), if I don't run the program with sudo or with Administrator privileges, it emits an exception or warning whenever it tries to read or save the data.

Obviously requiring the user to run the program with Admin privileges would be impractical. Optimally, I'd like the operating system to ask the user for permission.

This is quite silly, and removes half the purpose of Preferences. How can this be fixed?

Here's a summary what I need: I need my program to ask for permission from the operating system to save system settings.


Here is the error information

Here's the error when the when I try to read a node (because the node doesn't exist):

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.

And this is what happens when I try to write to a node:

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 Solutions


Solution 1 - Java

Unfortunately most of the answers you got here are wrong ... at least slightly. In the sense that the symptom is being treated, not the cause.

Let's recap. Java Preferences has two "trees": the user tree and the system tree. You can write your own backend to Java Preferences (called a backing store) but few developers do, so you end up with the JDK's default backing store. On a Windows platform this means the Win Registry, more specifically:

  • The user tree is written into HKEY_CURRENT_USER\Software\JavaSoft\Prefs (the OS user always has write access here)
  • The system tree is written into HKEY_LOCAL_MACHINE\Software\JavaSoft\Prefs (only an OS user with admin privs has write access here)

In summary: As long as your code doesn't attempt to use the system tree, you should be fine and shouldn't need to mess with assigning privileges at the OS level. The system tree is meant for "all users on the host" and the user tree is meant for the specific logged-in user. In your case I'm confident you can suffice with the user tree, so that is really your solution. Don't go messing with privileges, running as Administrator, and what not.

.... but there's more. Suppose your code deliberately doesn't touch the Java Preferences system tree, as instructed. You'll then still see this warning on Windows:

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

So what is going on? Did I give you the wrong advice ? Not really. Stay with me.

Diving into the JDK source code you'll see that 0x80000002 means HKLM, i.e. the place in the Win Registry that shouldn't be touched. Your code never references the system tree and yet you still see this warning !?? (At this point you must be ripping all your hair out ... as I did)

Well, this is one of the rare occasions where there really is a JDK bug. You can read more about it in this answer by me which I encourage you to read if you are interested in why subtle bugs can go undetected in the JDK for years. The bug has existed ever since JDK 1.4 but has only recently been fixed and not yet backported to JDK 8 (update: the fix has now been backported to version 8u192 onwards of the JDK)

Best advice

  • Make sure your code only references the user tree, not the system tree. It is only fair that the OS requires all kinds of privs for you to write to a system-wide location. If you really need to write into such a location then there really is no other solution than assigning privs, executing as Administrator or what not.

  • Ignore the warning. It'll go away once you are on Java 8 update 192 or later. The warning can be safely ignored.

  • Alternatively you can try to programmatically silence the warning. It comes from the JDK's Platform Logger, so something like this should work, albeit I haven't tried it myself:

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

Solution 2 - Java

This link is work for me:

Resolving the problem The work around is to login as the administrator and create the key HKEY_LOCAL_MACHINE\Software\JavaSoft\Prefs

Solution 3 - Java

It is possible to change the access rights of the registry entries. If you allow full access rights to HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Prefs to everybody, everybody will see the same set of preferences and everybody will be able to change them globally. I am aware that this is not a solution for software that is installed by customers, but it might be of use for somebody.

Solution 4 - Java

Modifying the answer based on feedback. This solution is probably overkill but ...

  • I suggest you change your store to write to a file instead of the registry (example)
  • A lot of java-based products ship with their own JVM. They do it so that they can run with a custom policy file (which would be needed in your case to write to a common location) and save on support issues (like outdated/untested JVM's being used)

Solution 5 - Java

Especially with Windows 7, the JVM has not by default the permission to write into the Windows registry where the backing store for java.util.prefs.preferences is located under MS-Windows.

When executing either the ReverseXSL transformer, or even the Regex tester program, one can get errors like: Could not open/create prefs root node Software\JavaSoft\Prefs at root 0x80000002. Windows RegCreateKeyEx

This does prevent registering a license. It does not prevent the software to perform transformations in the free software mode.

Fixing the issue is simply a matter of granting the necessary permissions to the registry root key at stake.

Run regedit.exe as administrator (regedit.exe is located in the c:\Windows operating system root directory). Go to key HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Prefs. Right click to set permissions. Check a mark in the Full Control check box for the user(s) that need executing the reverseXSL software.

Solution 6 - Java

Just Run the application as administrator, or if using eclipse, run eclipse as administrator.

Solution 7 - Java

This has finally been patched, in January 2019, in Java SE Development Kit 8u202.

This is the Patch Set Update (PSU), as opposed to the Critical Patch Update (CPU), 8u201. The difference is explained here. (The page uses Java 7 as an example, but it gets the point across.)

The download can be found lower down on the "Java SE Development Kit 8" page. (https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html)

Solution 8 - Java

The Answer by peterh already elaborated on the background, but I was searching for a fix and found it!

Since you can't touch the PlatformLogger itself, you have to void its message:

// 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);

This way the annoying Warning is gone without leaving any traces. Note that you only need to do this at the point where you are referencing the Preferences API for the first time in your program.

Solution 9 - Java

The fix is to run JMeter as Administrator, it will create the registry key for you, then you can restart JMeter as a normal user and you won't have the warning anymore.JMeter official site - changes

Solution 10 - Java

The solution for me was not obvious - it was to update my cryptography security jars from Oracle as it seems to be a key length restriction (I didn't believe it was related, until I tried it).

Download from Oracle website

The download contains instructions and explains:

> Due to import control restrictions of some countries, the version of the JCE policy files that are bundled in the Java Runtime Environment, or JRE(TM), 8 environment allow "strong" but limited cryptography to be used. This download bundle (the one including this README file) provides "unlimited strength" policy files which contain no restrictions on cryptographic strengths.

This apparently applies to Registry keys too

Solution 11 - Java

Go to your registry and create JavaSoft\Prefs\myapp under HKEY_LOCAL_MACHINE-->SOFTWARE

Create key name as Prefs and in that create a sub key as myapp, this will resolve the issue.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJonahView Question on Stackoverflow
Solution 1 - JavapeterhView Answer on Stackoverflow
Solution 2 - JavamorrxyView Answer on Stackoverflow
Solution 3 - Javakuester2000View Answer on Stackoverflow
Solution 4 - JavaqwertyView Answer on Stackoverflow
Solution 5 - JavaguestView Answer on Stackoverflow
Solution 6 - JavaAshuView Answer on Stackoverflow
Solution 7 - JavaKatrina EatonView Answer on Stackoverflow
Solution 8 - JavaxerufView Answer on Stackoverflow
Solution 9 - JavaArun GirdharView Answer on Stackoverflow
Solution 10 - JavaNick CardosoView Answer on Stackoverflow
Solution 11 - JavapratikView Answer on Stackoverflow