Home | FAQ | Contact me

Java Application Configuration

Configuration is often done using properties files or resource bundles. Here is a scheme exposed by Apache Commons that updates an internal record of resources as they change, triggered by the file modification timestamp.

In this context, "resource" means a string or other simple piece of data that is established external to the compiled code.

You must answer the question, however, do I even need this? It's very cool that Java objects might be updated automatically, but is this wise? Consider that properties configuring the some components of your application might be updated and influence their behavior faster while other components, accessing the same properties, may continue with the old behavior only because they no longer look at those properties or do not so frequently. It may be better merely to figure on bouncing your application, especially if it is a server, after an explicit property (resource) change.

This sample demonstrates very simple use of the Apache Commons Configuration stuff, in particular, the ability to reload when changed. This also demonstrates where one might keep resources and the path to them as needed by the configuration library, to wit: project-name/src/resources/application.properties.

Cons: Using commons-configuration-x.y.z.jar forces one to drag in a number of other Apache Commons libraries one may not wish to use (logging, for example). Libraries needed (versions variable; these are what I used to create this example):

Here's the output from running the program and changing application.properties live as it's running. To quit the application (in Eclipse), click the red square.

    TEST_PROPERTY contains "version 1"
    TEST_PROPERTY contains "version 1"
    TEST_PROPERTY contains "version 1"
    Jan 17, 2012 5:48:34 PM
    org.apache.commons.configuration.reloading.FileChangedReloadingStrategy
    hasChanged
    WARNING: File was deleted:
    file:/home/russ/blackpearl/workspace/TryStuff/bin/resources/application.properties
    Jan 17, 2012 5:48:34 PM
    org.apache.commons.configuration.AbstractFileConfiguration reload
    INFO: Reloading configuration. URL is
    file:/home/russ/blackpearl/workspace/TryStuff/bin/resources/application.properties
    TEST_PROPERTY contains "version 2"
    TEST_PROPERTY contains "version 2"
    TEST_PROPERTY contains "version 2"
    Jan 17, 2012 5:48:52 PM
    org.apache.commons.configuration.AbstractFileConfiguration reload
    INFO: Reloading configuration. URL is
    file:/home/russ/blackpearl/workspace/TryStuff/bin/resources/application.properties
    TEST_PROPERTY contains "version 3"
    TEST_PROPERTY contains "version 3"
    TEST_PROPERTY contains "version 3"
ApacheConfigurationExample.java:
package experiment;

import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.commons.configuration.reloading.FileChangedReloadingStrategy;

public class ApacheConfigurationExample
{
    private static final String     TEST_PROPERTY = "test.property";
    private static final String     RESOURCE_PATH = "resources";
    private static final String     RESOURCE_NAME = "application.properties";

    public static void main( String[] args )
    {
        try
        {
            String                       property       = null;
            String                       resPath        = RESOURCE_PATH + "/" + RESOURCE_NAME;
            FileChangedReloadingStrategy reloadStrategy = new FileChangedReloadingStrategy();
            PropertiesConfiguration      cfg            = new PropertiesConfiguration( resPath );

            reloadStrategy.setRefreshDelay( 1 );        // set a 1 millisecond delay
            cfg.setReloadingStrategy( reloadStrategy );

            Long    milliseconds = System.currentTimeMillis();
            boolean done         = false;

            while( !done )
            {
                Long now = System.currentTimeMillis();

                property = cfg.getString( TEST_PROPERTY );

                if( now - 5000 < milliseconds )
                    continue;

                System.out.println( "TEST_PROPERTY contains " + property );
                milliseconds = now;
            }
        }
        catch( ConfigurationException e )
        {
            System.out.println( "Screw-up during PropertiesConfiguration construction" );
            System.out.println( e.getMessage() );
        }
    }
}

As the example runs, I change the version number in an editor.

src/resources/application.properties:
test.property="version 1"