Reinventing java properties or using “Owner” library

Most of java developers use property files in their daily work. Basically we need them to configure our applications, to make our code more flexible and reusable. Unfortunately Java API for properties is very far away from perfect also most of developers are used to writing lots of the repetitive and routine code when accessing properties.

What do I mean? Let’s consider the following example:


// static fields
private static final String TIMEOUT_KEY = "db.timeout";
private static final int DEFAULT_TIMEOUT = 10;
// within some method
String timeOutString = properties.getProperty(TIMEOUT_KEY);
Integer timeOut;
try {
    if(timeOutString != null &&  !timeOutString.isEmpty()) {
        timeOut = Integer.parseInt(timeOutString);
    } else {
        timeOut = DEFAULT_TIMEOUT;
} catch (NumberFormatException e){
    timeOut = DEFAULT_TIMEOUT;
// using timeout

So in the example above we can see classical issues with accessing properties.

Issue #1 – Duplication of converting logic

try {
    timeOut = Integer.parseInt(timeOutString);
} catch (NumberFormatException e){
    timeOut = DEFAULT_TIMEOUT;

This try-catch is going to be placed in every place where you want to convert String to Integer, which leads to duplication. So if Integer property was changed to Long you would have to change it in all places where you use it.

Issue #2 – Duplication of fallback to default value

if(timeOutString != null && !timeOutString.isEmpty()) {
    timeOut = Integer.parseInt(timeOutString);
} else {
    timeOut = DEFAULT_TIMEOUT;

Unfortunately, I’ve seen many times a piece of code like one written above. Sometimes property value is being checked just for null, sometimes for emptiness, sometimes fallback value is used after unsuccessful conversion. In all cases same mechanism:

no effective value – use default

Issue #3 – Duplication of constants

private static final String TIMEOUT_KEY = "db.timeout";
private static final int DEFAULT_TIMEOUT = 10;

I guess most of you have ever seen such constants. Unfortunately, I faced many situation when constants were not extracted to a separate class and just were copy-pasted. So when we have service-A which uses property1,property2 and service-B which uses property1, property2 we would have 16 string constants.

  • 4 constants in service-A impl (prop1_key, prop1_default, prop2_key,prop2_default)
  • 4 constants in service-A test (prop1_key, prop1_default, prop2_key,prop2_default)
  • same for service-B impl
  • same for service-B test

Can you imagine how ineffective it is?

At this moment you may think that I’ve never heard about properties support in the spring framework or in Apache framework , but it is not true. I am aware of them and I am using them, but still they don’t solve issues mentioned above.  @Value annotation allows you to inject property value on context-startup and there is no ease way to reload injected properties ( I am aware only about spring-cloud). Apache framework provides lots of methods for conversion and mechanism of fallback to default, but still we need to duplicate constants which sometimes looks stupid, especially if you copy-them in your Junit test.

Here is  the moment when Owner framework enters the game. Basically it makes properties handling as ease as possible. This is how example above looks like using Owner:

    import org.aeonbits.owner.Config;
    public interface AppConfig extends Config {
        int dbTimeout();
// somewhere in a method
ServerConfig cfg = ConfigFactory.create(ServerConfig.class);
int timeout = cfg.dbTimeout();
//using timeout

Is not that cool? The general idea is that we are accepting convention over configuration which allows us to write as less code as possible. Also annotations in the library lead us to more declarative style rather than imperative.

Instead of describing Owner documentation , which is good enough, I would prefer to look at some example.

First of all we need to create maven project, I created one using
mvn archetype:generate + maven-archetype-quickstart

Then we need to add owner library via dependency


Then I created 2 properties file. One is called resources/ and the second one is resources/config/ I put the following content there:


//server properties

Then we can create config class. I created interface called AppConfig.

@Sources({"", "classpath:config/"})
interface AppConfig extends Config {

    int maxThreads();

    String databaseConnectionUrl();

    TimeOut dbTimeout();

    List<String> serverUsernames();

    URL serverBlogUrl();


Without @Sources annotation owner tries to find ${configclassname}.properties file in a classpath. Since I named files in another I can say owner need to load my properties files via @Sources annotation:

@Sources({"", "classpath:config/"})

In source you can use classpath resources as well as just file resources (e.g. “file:/home/”)

Lets go through define methods one by one:

  • maxThreads – no property with such name is defined, default value from annotation should be used
  • databaseConnectionUrl – no property with such name, but there is @Key annotation which will be used to get correct value
  • dbTimeout – is existing property, but class timeout was defined by me, so custom Converter which I defined in @ConverterClass(TimeoutConverter.class) should be used
    public class TimeOut {
        private int amount;
        private TimeUnit timeUnit;
        public TimeOut(int amount, TimeUnit timeUnit
        ) {
            this.amount = amount;
            this.timeUnit = timeUnit;
        public int getAmount() {
            return amount;
        public TimeUnit getTimeUnit() {
            return timeUnit;
    public class TimeoutConverter implements Converter {
        public Object convert(Method method, String s) {
            String[] values = s.split(":");
            int amount = Integer.parseInt(values[0]);
            TimeUnit timeUnit = TimeUnit.valueOf(values[1]);
            return new TimeOut(amount, timeUnit);
  • serverUsernames – such property does not exist, but again there is @Key annotation and @Separator, which means that values will be splitted using separator
  • serverBlogUrl – example of rich Convertion support, converting

Then I created a class ConfigDemo to show how to access defined properties.

public class ConfigDemo {

    private static void print(String value){

    public static void main(String[] args) {
        AppConfig configApp = ConfigFactory.create(AppConfig.class);
        print("Max threads:" + configApp.maxThreads());
        print("DB URL: " + configApp.databaseConnectionUrl());
        print("Timeout " + configApp.dbTimeout().getAmount() + " " + configApp.dbTimeout().getTimeUnit());
        print("Usernames: " + configApp.serverUsernames());
        print("URL: " + configApp.serverBlogUrl());


Here is the output of the program.

Max threads:10
DB URL: jdbc:mysql://
Timeout 10 SECONDS
Usernames: [thor, loki]

You can find this example on my github: owner-properties-demo.

As you see, it works pretty well. Now you can go much faster with your app configuration since there is no need to write dozens of lines to access , fallback or convert properties. All of that is already there.


If you are tired of writing routine and repetitive code for handling properties then owner it is something you should definitely try to use. You can be sure that is it stable, at least they use TDD and claim 97% code coverage. Also they are feature rich, which means that you will definitely find what you need.  In regards to me: if I need properties management in my next pet or production project  I will definitely use owner library.