Tidy config with Owner

A little library that delivers

It is a truth universally acknowledged that a single program in possession of a good configuration must be in want of a way to easily access it. (Jane Austen?)

Any non trivial software at some point needs a way to allow users to configure it. By far the easiest solution is to use a text file with some convention (ini, yaml, json, xml, you name it) and parse it at the start.

Java has support for property files since version 1, and it’s probably the easiest way to configure java programs. The class Properties has methods load and store to read and write property files. So far so good.

FileOutputStream out = new FileOutputStream("appProperties");
Properties prop = new Properties();
prop.setProperty("port", "1234");
prop.store(output, "comment");
. . .
Properties prop = new Properties();
FileInputStream in = new FileInputStream("appProperties");
String port = prop.getProperty("port");

Where do we keep the configuration in the program?
There are three common solutions:

  1. A singleton. Once read we can keep the Properties object as singleton and then we are be able to read from it anywhere in the code.
  2. A higher level object that wrap all the around configuration, typically it is called ConfigManager or PropertyManager. Then we can pass this object to any method which need to read the configuration.
  3. We parse the config and we create specific values object immutable to keep them logically organized.

The singleton solution is the easiest to implement, but it’s also the most fragile: if we want to change a configuration we have to check all our code, since it can be called everywhere. Then to any class which need them, we need to mock the singleton. Finally there could be some logic to access configuration and we need to remember to use same logic everywhere.

The manager solution has the advantage to keep all the logic together and it is usually easier to mock, since we own the interface. The problem is that we need to write more code, again and again.

The value objects are the cleanest solution but they require a lot of boiler place code to read the property file and set the value object. Or not?

Enter Owner.

Disclaimer: the author of Owner is a dear friend of mine and one of the best programmer I ever worked with.

As you may have guessed at this point, Owner is a library that load value objects from your configuration files, or create the config files from your objects.

Now I have a small project on GitHub that exposes a rest api to do simple mortgage like calculations. I use it as exercise and starting point for more complicated proof of concept.

Now I want a configuration file to specify the port to listen and the list of UserAccounts.

First step is straightforward enough: just add the dependency in Gradle (or Maven). Note that if you are using a java version older than java8 you need owner package, not owner-java8.

dependencies {
compile 'com.sparkjava:spark-core:2.6.0'
testCompile "junit:junit:4.12"
compile 'org.slf4j:slf4j-simple:1.7.21'
compile 'org.aeonbits.owner:owner-java8:1.0.9'

Step two: create an interface with all the properties you need. You can specify default values using annotation.

Note that all properties come properly typed, while using standard Properties class all property are String. For List properties you just have to specify values separated by commas.

By default Owner look for the config file inside the resources, with same package/file of the interface. I prefer an external text file, so I just have to specify the file location with another annotation. Note that I can even specify more than one location and the algorithm used to merge them!

Step three: you just have to call ConfigFactory.create and everything just work!

Owner can do much more than this: you can specify property separators, hot-reload, remote properties (Zookeeper), mutable values, etc. etc. Just read the documentation.

Have fun!