Apache Felix Preferences Service

The OSGi service compendium specification defines a general purpose service to store data persistently, so that they can survive the restart of a bundle or of the whole OSGi container. This service is not intended to be a full-featured persistence layer for OSGi bundles, rather a simple tool to store informations that can be used in various stages of the bundle lifecycle.

The service supports the storage of scalar values (boolan, double, float, int, long and strings) and byte arrays, arranged in a hierarchical model. While there is no limitations on the size of data objects stored, the specification clearly states that the Preferences Service is intended to store only small objects.

The entry point to the Preferences Service API is the PreferencesService interface. It provides access to different roots of Preferences trees:

  • a system root

  • any number of user roots The user root for a specific user is automatically created the first time it is requested.

User roots and system root are bundle specific, and cannot be accessed by other bundles.

Accessing the Preferences Service

If the OSGi platform provides a Preferences Service, getting a reference to it is as simple as doing a normal OSGi service lookup:

public class Activator implements BundleActivator
{
	public void start(BundleContext context) throws Exception
	{
		ServiceReference ref = context.getServiceReference(PreferencesService.class.getName());
		if (ref != null)
		{
			PreferencesService service = (PreferencesService) context.getService(ref);

			//...
		}
	}

	//..

To access the system root

Preferences systemRoot = service.getSystemPreferences();

To access a user root

Preferences mickeyRoot = service.getUserPreferences("mickey");

Store and retrieve value in Preferences

The Preferences interface offers some simple methods to store key/value pairs:

public void put(String key, String value);

public void putInt(String key, int value);

public void putLong(String key, long value);

public void putBoolean(String key, boolean value);

public void putFloat(String key, float value);

public void putDouble(String key, double value);

public void putByteArray(String key, byte[] value);

For each of these methods, a correspondent get method exists. Get methods always accept two arguments: the first to specify the key of the property to retrieve, the second a default value in case of not-existent property (or in case of errors). For instance:

public float getFloat(String key, float def)

As mentioned before, data can be stored in a hierarchical way. The following example shows how to create nodes under the system root to store data:

Preferences colorPreferences = service.getSystemPreferences().node("color");
colorPreferences.setString("background", "#eeeeee");
colorPreferences.setString("font", "#000000");

The Preferences interface offers different method to navigate the preference tree, like childrenNames(), parent() and node(String name). Check the Preferences interface Javadoc for a complete list.

flush() and sync()

Two additional methods of the Preferences interface can be useful.

  • flush() forces any change of the Preferences object to be saved in the persistent storage

  • sync() reload the content of the Preferences object from the persistent storage; before reloading, all the contents are saved