I'm working on a reasonably large (1000+ source files) J2EE application that makes extensive (some might say utterly excessive) use of external components - it requires in the order of 50 JAR libraries to run, over and above the standard J2EE ones.
And of course many of those JAR files have their own unique XML files to configure them.
And of course many bits information related to the configuration of the application (URLs, database details etc) have to be repeated in more than one of those XML files.
And there's no global way of doing this.
So the people who originally wrote the application came up with a scheme - they'd store the configuration values in property files.
But that only helped for things that got the values dynamically, for example by using the J2SE Properties class. All those external components they'd used didn't know anything about the application's property files, they only knew about their own unique little XML files.
So the people writing the application came up with another scheme - they'd embed tokens in all those little XML files, then use the Ant Filter task to replace them at build-time with the values from the property files.
"Job's a good 'un!" they doubtless exclaimed, flushed with their extreme cleverness.
Then I came along and had to maintain the beast, when I found:
- There are in excess of 50 of these properties, which makes configuring the application more than a little tedious and more than a little error-prone.
- The names of the tokens processed by the Ant Filter task and the names of the properties used to set their values mostly bear very little relationship to each other.
- There is no consistently-applied property naming scheme. There are in fact several inconsistently-applied naming schemes.
- Some of the properties are just renamed versions of other properties. Sometimes they are inconsistently renamed versions of other properties. Sometimes they don't appear to be used at all.
- It isn't clear when reading a property file which properties are only used at compile time by the Ant Filter task, and which properties are only used at run time. It's also unclear which ones are used at both compile and run time.
- The compile-time use of properties is a killer because it means the application can't realistically be reconfigured without recompiling it - because the use of the Ant Filter task means the compile-time property file values end up hard-coded in many different places. It's therefore pretty much impossible to produce a version of the application that can be deployed on more than one machine - for example for development or test purposes.
All this means that there's a whole series of bear traps set for anyone who innocently changes any of the properties files of the application, in the mistaken assumption that the application will actually take any notice of them.
I'm sure I'm not the only person to have been hit by this problem - how to configure multiple external components which all have their own XML configuration files - without having to hand-edit each of the XML files each time every time something changes, and without hard-coding the configuration at build time. However I'm damned if I know of a good way of doing it - although I can easily think up several not-very-good ways of doing it.
If you know, please let me know!