General

General
What is Java Config?

Java Config consists of a few classes that provide type-safe access to properties of a property-file. This makes it very easy for an application to be configurable.

An important feature of Java Config is the possibility to check your entire configuration on validity with a single call. Also, Java Config supports a lot of data-types that are common for Java projects.

Where can I find Java Config?

The easiest way to get started with Java Config is to use the zips provided at the Download page.

What's the latest version of Java Config?

You can always find the latest version of Java Config at the download page. Be assured that all new versions of Java Config will always be downwards compatible.

Where do I get help on Java Config?

The website you are currently visiting tries to answer most questions. Next to that, the JavaDocs provide more detailed information on the method calls and classes that form Java Config.

If you would more information feel free to send me an e-mail.

Using Java Config

Using Java Config
What data-types are supported by Java Config?

For a list of the currently supported data-types see this page .

How do I add a custom data-type to Java Config?

The requirement for new configuration get-methods is pretty easy: calls on this method should be be consistent. Before you add a new validation to your Config it's worth reading the design document. Having said this, here's a quick example of a new validation:

public class CustomValidationConfig extends Config {

    public static final String RESOURCE_NAME = "customvalidation.properties";

    public CustomValidationConfig(String resourceName) {
        super(resourceName);
    }

    public int getAmountOfLegs() {
        int value = getInt("amount.of.legs");

        if ((value % 2) != 0) {
            throw new InvalidPropertyException("amount.of.legs", "" + value, "even number");
        }

        return value;
    }
}
	

The use of InvalidPropertyException is optional; any exception that is thrown will be recorded. When an Exception is thrown, the validation method knows that the configuration is incorrect and will report this.

Can I change values at runtime?

No, an instance of a Config class is immutable. However, it is easy to extend your config class and override on of the methods, this is specifically useful for unit testing. See below for an example.

How can I make sure all my property names are in a certain format?

Sometimes it is desireable to have propertynames (the keys in the property file) share a common layout. For example, you would like to prefix all the property names in your file with the application name, so that this property file can be used in multiple applications without name clashes. You can achieve this by overwriting the getValue(String) method in Config. In the example below you will see that the property "magicnumber" is retrieved from the file. In the next version of that Config, not "magicnumber" is used, but "mycomponent.magicnumber".

public class CustomValidationConfig extends Config { 

    // constructor left out for brevity 
    
    public int getMagicNumber() { 
        return getInt("magicnumber"); 
    }
}
public class CustomValidationConfig extends Config { 

    // constructor left out for brevity 
	
    /** 
     * Make sure all values are retrieved from keys starting with
     * "mycomponent.". 
     */ 
    public String getValue(String key) {
        return super.getValue("mycomponent." + key); 
    } 
    
    public int getMagicNumber() { 
        return getInt("magicnumber"); 
    }
}

Why did you choose this strange format for the Date data-type?

The format of a propery that is read by getDate(key) must be in the following format: November 26, 2003 2:09:28 PM . This is the Java DateFormat that can be retrieved by the following call: DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.MEDIUM, Locale.US) . I choose this date-format because it is available in every Java implementation.

This Date format can be useful, for example to determine at runtime when the current executable was compiled. Use this format in Ant or Maven for the property-generating for that: MMMM d, yyyy hh:mm:ss a .

Example for Maven:

<ant:tstamp>        
    <format property = "timeforversion" pattern = "MMMM d, yyyy hh:mm:ss a" locale = "en" >      
</ant:tstamp>
   		

Can we still use our old property files?

Q: On our project we have a lot of existing property files which would require a lot of work to replace. Can we keep on using our current configuration files in Java Config?

A: Yes, certainly. Java Config uses standard Java property files, and thus support the full features of this format such as comments etc.

If you already have an existing property file, you might be interested in a simple utility that can be found in the CVS repository of Java Config (in directory othersrc). That class generates a Java class from an existing property file.

What Java version do I need?

Java Config is written to be as independent of external libraries as possible. However, the requirement when it comes to Java is strict: Java Config works with Java 1.4 only. The implementation uses regular expressions and chained exceptions, which are built-in in Java 1.4, but would have required external libraries for Java 1.3.



It's possible (if you really want to) to check out the sources and work around 1.4 specific features, but you're on your own in this. It would require a lot of effort to keep two different code-bases in sync. Anyway: Java Config is most useful in new projects, and if you are starting a new project you are not going to use Java 1.3 anymore, are you?

Design of Java Config

Design of Java Config
Why is the Config class not static?

Q: Why are the calls to the Config object not static? In my project I could use the following code, and with Java Config I can't!

String hostname = Config.getFtpHostname();
        

A: The use of static calls strongly reduces the flexibility of a class. For example, it is very common to use the following type of configuration in a project:

public class ToBeConfigured {
    private String ftpHostname;
    ToBeConfigured(Config config) {
    	ftpHostname = config.getFtpHostname();
    }
    public void doIt() {
        // connect to "ftpHostname"
    }
}
        

Now, in this type of configuration it's much easier to create a unit test. For example if we want to connect to localhost instead:

class TestConfig extends Config {
    ...
    public String getFtpHostname() { return "localhost"; }
}

public void testWithLocalHost() {
    // start local FTP server here.
    ToBeConfigured toBeConfigured = new ToBeConfigured(new TestConfig());
    toBeConfigured.doIt(); // will now connect to localhost
}
        

With a static Config.getXxx() call this would have been much harder to accomplish. This way of dealing with component-configuration (passing on a Config object in the constructor) is sometimes called Inversion Of Control (IOC).

Is the Config class thread-safe?

Yes. The initialization of the Config class takes place in the constructor, after which the contents of the Config class will never change.

A (documented) exception is the use of the constructor that takes Properties as its argument.