13

I have a Java application that reads from the Preferences by using:

Preferences prefs = Preferences.userNodeForPackage(MyClass.class);
prefs.get((String)key, "");

On a fresh Windows 8 machine this fails with:

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

Error code 5 is access denied.

I can't find anything I'm doing wrong. Google and SO searches give old results relating only to Windows Vista/7 where one was wrongly using systemRoot (How can I write System preferences with Java? Can I invoke UAC?).

The error can be "cured" by creating HKLM/Software/JavaSoft/Prefs and setting permissions to HKLM/Software/JavaSoft as mentioned here Java: java.util.Preferences Failing. But this is not something I can require my users to do when they install the program.

So I'm looking for a better solution. My last ditch effort is to simply write to file but I'd like to avoid that. This also seems related I'm trying to use Java Prefences from XML WITHOUT using Windows registry, but I see a Registry-related message but it was down voted without an answer.

At current I suspect a Win8 JVM bug...

Questions

  • Does any one know of a solution that doesn't involve writing files?
  • Why does the same code work perfectly fine in Windows 7 but fails miserably in Windows 8?
Community
  • 1
  • 1
Emily L.
  • 5,673
  • 2
  • 40
  • 60

1 Answers1

13

I recently started noticing a same warning and thought it means that registry cannot be written. But upon closer inspection I noticed that all preferences where successfully updated in HKEY_CURRENT_USER anyways. So I got curious why I'm seeing this warning.

It turned out that the culprit is this static member variable: WindowsPreferences.systemRoot

Looks like Java tries to initialize WindowsPreferences.systemRoot just in case it is used later on by the program, and that initialization obviously fails if the program is not ran as administrator.

Since you're using Preferences.userNodeForPackage(), you will never need the systemRoot, therefore you can safely ignore that warning.

Of course, this is a horrible practice that Java tries to initialize systemRoot when it's not requested.

Update: I tested this problem in various Java versions and concluded that this bug was introduced in Java 1.7.0_21. It worked fine in Java 1.7.0_17 simply because the installer of that version would create the "Pref" folder in registry! Of course even in that version if you were to delete "Pref" from registry then it would stop working, so it was a silly solution on the part of Oracle to begin with. I will fill a bug report.

Update 2: The warning message is not a bug. It seem to be the intended behavior: http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6809488

Saeid Nourian
  • 1,606
  • 15
  • 32
  • Yes, the problem is that this isn't an warning in my case but the JVM simply dies. Because it cannot create that key which doesn't exist and I don't need :/ But yeah annoying it is. – Emily L. Sep 17 '13 at 19:47
  • Strange that it would crash the JVM. In my case it continues to run normally after printing the warning. Can you post the crash log? – Saeid Nourian Sep 18 '13 at 18:40
  • I updated my original response. Looks like Java 1.7.0_21 introduced this bug. – Saeid Nourian Sep 18 '13 at 19:33
  • It was on a customer's computer over teamviewer, I'll see if I still have the screenshot- Here it is! http://imgur.com/D8bkOBh – Emily L. Sep 19 '13 at 19:07
  • The exception looks to originate from my code but that code works even if the read fails... – Emily L. Sep 19 '13 at 19:35
  • So it doesn't crash your JVM. It simply throws an exception. The exception is coming from HardpointType.java. My guess is that HardpointType tries to read something from systemNode instead of userNode. The systemNode returns null which is probably why you get Unknown HardPoint Type error msg. – Saeid Nourian Sep 25 '13 at 19:05
  • What is confusing me is that the read was performed with a default value to return incase there was no data (`prefs.get((String)key, "");`). The same code worked perfectly on multiple win7 machines on the first try, and they didn't have the registry key written either... So I wonder what really went on there. I don't even have a windows8 machine to test on. – Emily L. Sep 27 '13 at 08:22
  • Yes, the default is "" which is still an invalid value, isn't it? Hence the "Unknown HardPoint Type" error msg. In win7, have you tried removing Pref from registry to see if it still works? – Saeid Nourian Sep 27 '13 at 17:35
  • Thats what I said in my post :) It works in win7 even when the default "" is returned. Even with pref removed... – Emily L. Sep 27 '13 at 21:53
  • Have you tried debugging ItemDB.java to see what value it's passing to HardPointType? Put a breakpoint on ItemDB.java at line 97. – Saeid Nourian Sep 30 '13 at 17:38
  • As I said, I don't have a windows 8 machine (or even a license) to test on. The crash occurred on a user's PC. I have since then made a workaround using `Properties` instead and writing to an XML file. The only way that could have happened is if `get(key, "")` returned anything else than the empty string or a valid entry. I'm assuming some kind of junk came out. In either case unless I get access to a win8 machine someway I'm leaving this as it is. The workaround works and isn't too horrid. Thanks for your help though :) – Emily L. Oct 01 '13 at 10:09
  • You've mentioned you filed a bug report. Any chance you can provide a link? – jdknight Nov 02 '13 at 16:22
  • 1
    Unfortunately the bug report didn't go through. Oracle seem to simply ignore most of bug reports. Looks like even people at Netbean tried to file a bug report for this very same problem and they didn't succeed either: https://netbeans.org/bugzilla/show_bug.cgi?id=234894 – Saeid Nourian Jan 24 '14 at 17:43
  • Looks like the issue with printed error message was already reported and it's not a bug. It's indented behavior: http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6809488 – Saeid Nourian May 21 '14 at 14:05