Configuring Java Applications

Posted by Kerry Wed, 14 Mar 2007 13:05:00 GMT

Steven Colebourne: Configuration in Java - It sure beats XML!

Is the Java community slowly remembering what’s good about Java? I’m talking about static typing.

I can’t count the number of times I’ve had this rant. The article is mostly inspired by being sick of editing XMl files which can become tiresome and error prone when they start getting large or numerous.

There are a few caveats that need to be made when thinking about configuration, in no particular order:

  • When the configuration is about setting up how an application works, and it doesn’t change per environment then use the language you are writing your application in. If the language isn’t good enough to handle setting up some configuration, then maybe your using the wrong language? It’s a good idea to use a Fluent interface when thinking about configuration languages, in fact it’s good to think about them all the time.
  • If a property can change per deployed environment then it’s better to externalise that from the code. As a commenter on Steven’s post pointed out, having to explode an EAR/WAR to change where some log files go isn’t very cool for somebody deploying a third party app. Often it pays to tokenise config files and then have an automated detokenisation process which provides the actual config values per environment. Deployers may not have the skills to go diving into a piece of code to change it, and it would be a PITA for them if they had too. Property files work well for them.
  • Think hard about what values are really going to change, get this wrong and configuration can become a nightmare. Try and go with convention over configuration. Define your deployment environment and be firm about not adding extra configuration because “you might need to change this value in the future but we don’t really know”. If it’s going to change in the future then change it in the future. Obviously this doesn’t apply for things that will always change, e.g. IP Addresses.

As an aside to all this, I’ve recently gone through the experience of moving all of my current project’s configuration from xml/property files into a Configuration database. Now when an application starts up it registers itself with the configuration service, if it doesn’t have any configuration it will be given a copy of a default set of values. We have an admin console where users with appropriate privileges can edit and add new values, or reset values back to defaults and so on. This way we have zero(almost) configuration packaged with an application. Applications identify themselves, get given a configuration, and off they go without any help from us. If a new team comes along and needs to use one of our apps they just take the application and deploy it as is. We can see it in the admin console when it gets started and then edit, or give the appropriate priveleges to one of their administrators so they can, the config that they need.

Looking up the configuration is done through a common JNDI name which then points the application to the correct place, this can be overriden if necessary which is why the “almost zero” configuration per app, it’s totally optional and it works by convention if it can.

The configuration is also cached by a client framework so updated values will be available when the application next reads them. This is useful for log levels and the like where you might want to up the priority to debug to do some debugging for a while and then set it back to error when your done.

We created a basic taxonomy of Tags that an application can use to identify itself, these are inserted into the application during the build process. Examples of tags are:

  • The application name
  • Which type of appserver the application is going to run in

There are a few more specific to our domain, but you probably get the idea. In the admin console we can search for different Tags which allows us to find all instances of an application that are running. This will include developers machines, integration environments, test environments, and third party environments we have no control over.

Testing was something we didn’t really consider upfront, which was a mistake. It was soon obvious that we needed to be able to bootstrap a configuration into a Unit Test(The config framework itself did have unit tests). Luckily the interface wasn’t too bad and with a simple mock JNDI environment we were up and running. It adds some overhead to the setup of a test fixture but isn’t all that bad.

Another benefit to this approach was when an application registered itself it provided it’s manifest file as part of the identification process. We now have all the version information for each application running in all our environments. This becomes highly valuable when supporting deployments in third party environments which we have no access too.

Us: What version are you running?

Them: Not sure, how do I find out?

Us: Go to the filesystem, find the deployed application, open the manifest, tell us what value attribute X has.

Them: How do I log onto Unix?

Us: Err…

Now we just look in the admin console, find out which version they have and get started looking at the problem. Not having access to an environment can be a pain when trying to find out which version and configuration an application is using. Now we just don’t have that problem.

It’s no silver bullet that’s for sure, but it does ease the pain of having to configure for many many difference environments.

Trackbacks

Use the following link to trackback from your own site:
http://blogs.divisibleprime.com/ronin/articles/trackback/810

Comments

Leave a response

Comments