Skip to main content

How to store preferences?

Posted by malenkov on April 21, 2009 at 11:00 AM PDT

The Preferences API can be used by applications along with the installed security manager that enables using the preferences permission. However, WebStart-based applications cannot permit preferences only. You can permit all or deny all by using a jnlp-file. So, how to store user preferences for unsigned applications deployed through Java WebStart?

Java provides the Preferences API to store and retrieve user and system preference and configuration data. These data are stored persistently in an implementation-dependent backing store. Typical implementations use Windows Registry or UNIX flat files. The Preferences API is designed as the Service Provider Interface (SPI). Therefore, you can provide custom implementation of the PreferencesFactory class that will be loaded on demand. But you can't use the Preferences API with your custom implementation, because the static methods of the Preferences class throws SecurityException. Why?!

The PersistenceService class is provided to store data locally on the client system for JNLP-based applications running in the untrusted execution environment. So, it is possible to create a custom implementation of the Preferences class, but we cannot fully use its functionality, because static methods cannot be overridden.

That's why I have created the PersistencePreferences class that allows to store user preferences for unsigned applications deployed through Java WebStart. Additionally, I have created the MemoryPreferences class that can be used as a temporary storage while an application is running. It makes the preference operations transparent. Consider the AppletPrefs applet that uses the following method to choose an appropriate node that holds the application preferences:

private static Preferences getPreferences() {
    Preferences prefs;
    try {
        prefs = Preferences.userRoot();
    }
    catch (SecurityException disabled) {
        try {
            prefs = new PersistencePreferences();
        }
        catch (Exception unavailable) {
            prefs = new MemoryPreferences();
        }
    }
    return prefs.node("Vendor Name").node("App Name");
}

Signed JNLP applet

The signed applet above enables all permissions in jnlp-file. On Windows it stores its preferences in the Windows Registry. You can check them using the regedit command.

Unsigned JNLP applet

The unsigned applet above stores its preferences by using the JNLP persistence service. Try to reload the page to ensure that all tabs and their content is saved.

Update: Hmm... This applet throws the BackingStoreException. Seems the reason is that the location of the jar-file differs from the web page location. This applet works here. What a pity! It was an interesting idea. But you can try to start the unsigned applet as a Java WebStart application. It works as expected:

Simple unsigned applet


The applet above is the same as the previous one, but it is deployed as a usual applet. Therefore, it cannot access the JNLP services and does not reload data on the page restart.

original post

Related Topics >>

Comments

How to store preferences?

These are all very practical tips, I'll admit they are more than I expected to find. I know it all about the regedit, I even have a registry cleaner application to keep my files in perfect order. This command is not that difficult to handle after all...

I still find storing in the application install directory better than on any home dir. For my part, I don't mind if things get stored in the Windows registry. It's only a few hundred bytes anyway. I doubt this will enlarge the registry. From a user's perspective the storage only has to be "invisible", at least that's what I found out. Home dirs are highly sensitive, other dirs aren't. I also like the fact that some installers, I mean deinstallers, leave some files on the local harddisk. Like this the user knowns the leftovers can be manually deleted from the install dir or backupped. This usually hints no leftovers in other places.

It's default implementation of the Preferences API on Windows. FileSystemPreferences are available only for UNIX systems...

I consider storing settings in the Windows registry as a bad idea. I said that already 10 years ago when everybody started to use the registry under Windows. Then Microsoft themselves told not to write everything to the registry because it gets pretty bloated. I still consider simple text files that can be edited also easily by hand as the best option. Is writing a file to user profile/home folder possible from within jnlp? Regarding the comment of suryad: I assume that the sample (didn't try it) write to user part of the registry and not to the machine part.

Only from the first applet that is signed and allows to do everithing. The second one uses JNLP persistence storage.

Interesting post...but did I read that right? That you can write straight to the Windows Registry!?! Security concerns anyone?

Thanks for mentioning not to pollute the user's home dir. Investigating, I find cases in my software too, where it is not necessary to create a folder in the user's home dir - in some cases I don't store any information there but "automatically" create the path there (not to miss the path later when needed). I will correct this. One basic problem is: You don't want to pollute the application folder with settings nor the home dir - so where to put? Actually you could make it configurable, but then: Where to store the link to the config folder/file? On Linux you could use etc - is that better? On Windows it is already more difficult - "All users" profile is an option. Anyway, you need to put effort in finding out an adequate standard folder. Regarding the preferences API: Polluting the Windows registry is either worse then polluting the home dir! Your customers may not notice but may get polluted even more. Microsoft themselves told a while ago not to write everything to the registry as it then gets huge. - Remember that it is a few files only. So registry is clearly not an option.

We had this discussion on the mailing lists some weeks ago. Many users feel *really* annoyed by having applications create files unasked on the users home directories. Some of my customers think my software is inferior until I tell them. For my part I don't like the user dir storage mechanism, too. It unnecessarily clutters every user's home dir. After all, who wants something as unimportant as window settings, file paths and the likes saved in their home directories? I prefer invisible locations for preferences and other session data. If you feel some piece of data is really important, you can still save it somewhere else.

yeah, I have seen that the Preferences API has this strange complete different behavior on the different OSes - therefore I don't use it. I am writing options to simple text files into user home folder or to application folder.