The project I’m currently working on uses a simplistic object store for persistence. The original authors, in their collective wisdom, decided that whenever something needed to be saved they would save it to a hashtable, and use Java serialization to save that to a file.
In a way I can see why they did. It’s a quick way of getting a simple to use object store. The project has been through several revisions since, but the data store stayed the same. It should have been replaced with something more robust a long time ago. I’ll explain more after the jump …
A data store like this can (and has) lead to some problems. Firstly, if the object store becomes corrupt, then all your configuration data is effectively lost. If this were to happen, the application would not be able to recover.
While we strive to maintain configuration through an upgrade, model objects can change between revisions. This makes data safe upgrades risky. Since we are relying on Java to serialise version N of an object into a class with version N+1 on the class path. If the object has changed significantly between version N and N+1, erratic behavior can result.
Next, the data store doesn’t afford easy access. There’s no easy way to instruct a customer in how to recover a corrupt file, or even recover a lost username or password stored in the data store. You have to deserialise the whole hashtable and all objects contained in it to get anywhere.
Finally, a feature customers have been asking for is the ability to export the configuration of one instance of the application and import it into others. Again achieving this with a serialised data store is possible but not ideal, as there will always be some subset of configuration values specific to the instance which you don’t want to share across all instances. There’s no easy way to split and merge configurations with such a data store.
As a result, I’m working towards replacing this file with an INI implementation. The hope is that once we can read and write these configuration values to a text file, they become easily splittable, mergable and shareable across instances.
As an example, a typical ini file could look something like:
[section1] ; this is a comment! var1 = foo var2 = bar [section2] var1 = doo
To achieve this I decided to give Apache Commons Configuration a go. I chose this over Ini4J as the documentation for Commons Configuration seemed better. That said, I have had some false starts with the library.
Firstly I had expected Commons Configuration to be a standalone library. I was mildly surprised to find it depends on Commons Lang, Commons Collection and Commons Logging. Next, I took a trip through the examples posted on the Commons Configuration website. They tend to deal with using the library for XML configuration files. There weren’t any examples of manipulating INI files which I could find, though it wasn’t difficult to find that HierarchicalINIConfiguration was the class I needed for INI manipulation.
Next, I tripped over multithreaded use. HierarchicalINIConfiguration is not thread safe so you have to provide your own external synchronization for it in the case you need multi-thread access. As I do, I decided to wrap it in my own API to control access from the wider system (and enforce thread safety).
Once these issues had been solved everything was looking good until I tried reading values back from the INI created. For the most part values can be easily read through the HierarchicalINIConfiguration class. That is unless your INI section name or key name contains dots (.).
Given the example INI above, HierarchicalINIConfiguration internally represents var1 in section1 as “section1.var1 = foo”. If you have dots in either the section name or key name, HierarchicalINIConfiguration has difficulty reading the value back from the INI.
Now that these issues are out of the way, my work continues to refactor the system at large to read and write their values to the INI. So far appart from these minor hiccups, the approach seems promising.