18

I've been working with the java.util.prefs.Preferences functionality (in Java 8, on a Windows machine). And it works, where I can write new keys to the Windows Registry. So, I use Preferences.systemRoot() to get the Preferences object for the system, and then use the node() method to get a Preferences object that maps to a node in the Windows Registry. And it's creating things fine.

The Key I'm using for the Node is a String in all capital letters ("RBI"). When I look at the node in the Windows Registry, it comes up as "/R/B/I", with forward slashes in the name.

I thought this was odd, so I've dug around a bit And it looks like this is intentional. I found the class that provides the implementation of Preferences on a Windows environment (java.util.prefs.WindowsPreferences) and the method is uses for building the values sent to the windows registry is a static method toWindowsName. In the JavaDoc for that....

/**
 * Converts value's or node's name to its Windows representation
 * as a byte-encoded string.
 * Two encodings, simple and altBase64 are used.
 * <p>
 * <i>Simple</i> encoding is used, if java string does not contain
 * any characters less, than 0x0020, or greater, than 0x007f.
 * Simple encoding adds "/" character to capital letters, i.e.
 * "A" is encoded as "/A". Character '\' is encoded as '//',
 * '/' is encoded as '\'.
 * The constructed string is converted to byte array by truncating the
 * highest byte and adding the terminating <tt>null</tt> character.
 * <p>
 * <i>altBase64</i>  encoding is used, if java string does contain at least
 * one character less, than 0x0020, or greater, than 0x007f.
 * This encoding is marked by setting first two bytes of the
 * Windows string to '/!'. The java name is then encoded using
 * byteArrayToAltBase64() method from
 * Base64 class.
 */

So, the Simple encoding will, for capital letters, add a forward slash.

Does anyone know why this is required? I had thought that the Registry could handle case-sensitive values, but this seems to indicate that it can't?

I can work around this, I'm just curious why this was done.

EdH
  • 4,918
  • 4
  • 24
  • 34
  • Sounds like they're trying to make the naming scheme case-sensitive. – Harry Johnston Apr 11 '14 at 01:24
  • Agreed, but using RegEdit I can enter Case sensitive strings (there are plenty of them in there already). And using other tools that option was there. Perhaps it's some workaround with the calls into the native methods ultimately being used. – EdH Apr 11 '14 at 04:26
  • It looks like it's encoding the String as a byte array. Which is fine. Now, the only reason I can think of (those last four words the key ones) of doing this would be if you didn't have different byte values for lower and upper case letters. But, again, as far as I know of, lowercase and uppercase letters do have different byte values. So, it's not really necessary? I must be missing something – EdH Apr 11 '14 at 04:38
  • 3
    No, names in the registry are case-preserving but not case-sensitive. You can't have a value named "Fred" and a value named "fred" in the same key. – Harry Johnston Apr 11 '14 at 09:38
  • Interesting. I wasn't aware of that. – EdH Apr 11 '14 at 11:45

1 Answers1

21

I was curious as you and I found the following explanation:

Registry-Keys are case-preserving, but case-insensitive. For example if you have a key "Rbi" you cant make another key named "RBi". The case is saved but ignored. Sun's solution for case-sensitivity was to add slashes to the key.

Registry-Values are case-sensitive (and, of course, case-preserving). I don't think it was Sun's intention to add the slashes to the values as well, but somehow it slipped into the code. It seems to me, that this bug wasn't found for a long time. When the bug was discovered, many systems already depended on the wrong implementation, so they never removed it to retain compatibility.

If you don't like the slashes in your Registry-Values, you may be interested in this implementation.

Community
  • 1
  • 1
MyPasswordIsLasercats
  • 1,610
  • 15
  • 24