Points of Intervention

We've got a problem. The problem is that there's this library that we have to use which needs to be configured using something other than code. Through an XML file, perhaps, or an LDAP schema. This is fine if the configuration is set in stone, but it's not. For the sake of efficient integration testing you want to be able to replace chunks of the system's configuration between tests, or perhaps you want to only set up a subset of the configuration. What can you do?

Let's take a step back and think about the various points at which we can intervene in this system:

  • By using the normal configuration mechanisms, making the library re-read these with every test
  • By somehow subverting the configuration mechanism, perhaps by noticing that certain system properties are used for default values
  • By plugging in a new configuration mechanism which can be manipulated in code
  • By inheriting from key classes in the library and configuring it to use those instead
  • By inheriting from key classes in the library and forcefully injecting them using reflection
  • By re-writing part of the library and submitting those changes back to the main development trunk
  • By taking advantage of class-loader ordering, and placing overridden but binary compatible version of key library classes in an earlier class-laoder (that is, the class has the same public interface, name and package as one in the library)
  • By the "nuclear option" of using AOP and wrapping any offending pain points

I'm sure that this list isn't complete (doubtless I'll wake up at 4 in the morning with another bright idea) but it's enough to get us going.

The interesting thing about this list is that the amount of political resistance tends to increase as you head further down it --- it tends to be easier to get acceptance of the use of "official" configuration mechanisms or extension points than it is to get buy-in for minor tweaks to the library. This in turn is easier than trying to persuade people that the use of AOP is a sane course of action. The use of AOP can be a lot like trying to trim your nails with a chainsaw: you can do it, but it's more than likely going to end up in a bloody mess unless you're very careful.

So, we have our list of intervention points. How to use them?

My preference would tend to be something that's obvious and which fits into the overall philosophy of the library. As such, providing a new configuration mechanism through an existing extension point or contributing a change to the library back would be the avenues that I'd want to explore first. Constantly spooling files to disk seems a little distasteful to me, and sometimes libraries are written in such a way as to prevent reloading once they're up and running. Additionally, the reading of config files can take some time, as anyone who's tried it with Hibernate can probably tell you, so it's not an ideal solution.

Once those possibilities have been exhausted, my Perlish tendencies tend to show and I start to reach for reflection. If the library is lousy with final classes, then AOP or class-loader abuse starts to look like a decent option. I'd want to step outside and get some air before pressing on with that plan....

Where am I going with this? Good question. I'm not sure, but I've been thinking about the various points at which a developer can intervene in a system and thought it might be nice to share. What do you like to do? How do you deal with these issues?


Simon Stewart on Friday, 02 June, 2006

Posted in: /tech/java

You may comment...


Categories