1

I have recently started working in Java. I am trying to find a good way to specify my application's configuration values in an easy to read way. I'd like the ability to create a base configuration file and then include in a derived configuration file that also allows overwriting the values in the base file.

Not sure if the java properties file provides the second feature. After searching on google I found apache commons configuration and ini4j but I'm not sure if they are actively maintained or how many people are actually using those.

Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332
akhil
  • 839
  • 3
  • 8
  • 15

1 Answers1

6

An easy option is java.util.Properties, which not only supports loading configuration data from key=value and XML files, but also directly supports the hierarchical defaults you describe.

For example:

Properties base = new Properties();
base.load(new FileReader("base.cfg"));

Properties custom = new Properties(base);
custom.load(new FileReader("custom.cfg"));

// 'custom' defers to 'base' for properties that were not in "custom.cfg".
// custom.remove(key) can be used to restore a default from 'base'.

Note that Properties does not have built-in support for grouped / hierarchical properties (e.g. an XML tree or an INI file with sections), but will generally get the job done in many cases.

It is possible to load the base configuration after the custom configuration as well if, for example, the custom configuration contains a property that specifies the base file name (this may be useful given some of your comments below):

Properties base = new Properties();

Properties custom = new Properties(base);
custom.load(new FileReader("custom.cfg"));

base.load(new FileReader(custom.getProperty("basefile")));

By the way, both libraries you mentioned (Apache Commons Configuration and ini4j) are in good working condition. The Apache library has support for a wider range of formats and is more actively maintained, but ini4j is mature (been around for about 10 years and INI files haven't changed) and also works well. I've personally used both a number of times and they have always delivered as promised.


All null / exception handling left out of examples for clarity.

Jason C
  • 38,729
  • 14
  • 126
  • 182
  • 1
    It's far from perfect, but this is where I'd start until it proves insufficient. – Alex Apr 09 '14 at 21:19
  • Thanks Jason. Your reply is very informative. The problem with this approach is that I have to program each custom file I want to include. Is there a way to avoid that so that I just specify one file and that file has a statement to include all base files? I had programmed in C# before and there we used an ini file where at the top we would use include=file1.ini,file2.xml,file3.xml to specify all the files that need to be included. – akhil Apr 09 '14 at 22:15
  • @akhil `Properties` does not support anything like that (I'm not sure of any configuration utilities that *do*, but that doesn't mean there aren't any). You would have to implement it in a way similar to your C# + INI method; load a file, read the `include` and load those files before reading the rest of the values from the current file. – Jason C Apr 09 '14 at 22:26
  • 1
    @akhil If you're willing to go to the trouble, you could keep all your config files in a certain directory, list them using java.nio.file.DirectoryStream (or whatever), sort the listing so that config precedence works in some consistent way, and then combine their settings in a simple loop. – CCC Apr 09 '14 at 22:35
  • @akhil It also might be worth thinking about what you actually *need*; for example, do you need to be able to include multiple files? Does that match your intention and is it useful in practice? Or is your intention to specify some single base specification to serve as a default? Both are valid, but it's sometimes easy to forget about the specific situation we are in and over-think design of generic solutions (and it's especially easy to go down a rabbit hole when there are many options that accomplish the same goal). – Jason C Apr 09 '14 at 22:51
  • Yet another possibility is to specify a list of files to load, in order, on the command line (similar to CCC's good suggestion, but a different option for the source of the ordered list). – Jason C Apr 09 '14 at 22:54