Creating a Better FileSystemPreferences Framework

BKit.jpg

I have spent the last few days - on and off, talking to a developer about the need for a global user Preferences system. The one that comes with most JDKs is decent but there's a problem using the one that ships with Windows - it uses the Registry. That's not the issue as much as that sets up the problem. The user preferences part of the Registry can be put in an unreliable state if you log into two machines and aren't very careful about what you're doing.

Imagine you have two Windows boxes: A and B. On these boxes you have an application - it resides on a server so it's up to you where you launch it. You decide to log into A and then B and launch the app on A. You move a few windows, make a few changes - basically change the Java Preferences values. When you exit the app, your changes have been written to the Registry on A. So far so good. If you logged out of B before logging out of A then the Registry will remain correct and the changes from A will be written to the PDC. But what if you log out of A first?

Well... your changes will be written to the PDC, and then when you log out of B you're going to have that Registry's state written to the PDC. You've lost your changes. No way to get them back.

This is a common problem for a lot of our users. They have multiple machines and we'd like to use Preferences as it's easy and clean, but there is this problem. On Linux/Unix this isn't an issue because the user Preferences are stored in your Home directory. Write it there and you're good to go. Login/logout order doesn't matter. But it does with Windows.

So we decided that it would be a good idea to use the FileSystemPreferences system that's used in Linux for Windows. The problem is that it's not available in the Windows JRE because it's not considered necessary. What a mistake. I've spent the day getting the source code for the FileSystemPreferences and FileSystemPreferencesFactory and creating BKit versions of them that are cross-platform.

That last part was the real key. The original source code for the FileSystemPreferences wasn't because it used three native methods that really didn't have to be used, but were used because they didn't take advantage of the NIO additions in JDK 1.4. I cleaned up all the code, got rid of the native methods, removed the silly XML dependency and used the PList work I had just done on the BKHashTree to serialize these maps to files.

In the end, we have something that's a drop-in replacement for Preferences that will work on all platforms. This means that we can point the user Preferences to a shared disk and so all flushes of the Preferences will write to the files and there won't be any problems like we're having now with the Registry. This is going to make things much nicer.