typesafe

Archive for the ‘configuration management’ tag

Java webapps and externalization of their configuration

without comments

One of the most annoying things, in my opinion, is application’s configuration management. Naturally, it depends on operating system and hardware environment, but the most frequently moving target is whether your app is running in development or production environment which forces you to change configuration files every time you copy your files to the production or beta-testing server.

Yes, I’ve previously written on automated build process where I mentioned config file generation from template, although in my particular case, I developed that build process for an existing application. For a new application, I wanted something cleaner.

As I’m writing this new web application in Java, my first idea was to make use of the existing J2EE standards, particularly, JNDI: just create my own configuration POJO class and store it in the servlet container (per-application scope) and reference it through some constant URL like java:comp/env/bean/ApplicationConfig.

I ran into two problems in no time:

  1. Servlet container (either Tomcat and Jetty), on its startup, threw ClassNotFoundException because it didn’t know anything about my ApplicationConfig class until my webapp context was loaded. That problem can be solved by copying that particular *.class file to the container’s class path, which then reveals next problem
  2. ClassCastException gets thrown when assigning pointers to objects of seamingly identical class (cannot cast foo.bar.Application to foo.bar.Application). Now that occurs because instances of these classes come from different class loaders, i.e., server and application.

That as kind of disappointing because I’ve been thinking that storing POJOs in JNDI is kind of easy, convenient and even recommended practice.

Eventually, I opted for a simpler way - a configuration file :), location of which is defined outside of application itself - a system property. I found it is easy to define in production environment as a -Dfoo.bar.config.location=... in JAVA_OPTS or similar environment variable. In development environment, I use Jetty Maven plugin which has systemProperties configuration argument.

My configuration class I designed as a singleton class, something like this:

public class ApplicationConfiguration {
    private String foo;

    private static ApplicationConfiguration instance;

    private ApplicationConfiguration() {
    }

    public void getFoo() {
        return foo;
    }

    void setFoo(String foo) {
        this.foo = foo;
    }

    public static ApplicationConfiguration get() throws Exception {
        if (instance == null) {
            String configLocation = System.getProperty("foo.bar.app.config.location");
            Properties properties = new Properties();
            properties.load(new FileInputStream(configLocation));

            instance = new ApplicationConfiguration();
            instance.setFoo(properties.getProperty("foo.bar.property"));
        }
        return instance;
    }
}

Now, I could reference my application’s configuration from anywhere using ApplicationConfiguration.get() method.

The last problem I had to solve was how to inject this configuration POJO in my Spring beans. Luckily, I could use the static factory-method bean tag attribute, something like this:

<bean id="appService" class="foo.bar.ApplicationService">
    <property name="configuration">
        <bean class="foo.bar.ApplicationConfiguration" factory-method="get"/>
    </property>
</bean>

That basically satisfied my requirements and saved me a lot of hassle with re-deploying and editing config files in different environments.

Written by martinsb

April 23rd, 2009 at 8:54 pm