Designing a library for reading layered application settings in Java
Tags: settings, properties, java, deserialization
Published: 2021-08-29 09:52:22

---
title: Designing a library for reading layered application settings in Java
published: true
date: 2021-08-29 00:00:00 UTC
tags: Settings,Properties,Java,Deserialization
canonical_url: https://MihaiBojin.com/application-settings/reading-application-settings-in-java
cover_image: https://mihaibojin.com/static/e1ac4dd65e02c65689d331a94ef78196/7d6ed/001-sigmund-f0dJjQMhfXo-unsplash.webp
series: Designing a library for reading application settings in Java
---

![Photo: Clock mechanism](https://MihaiBojin.com/static/e1ac4dd65e02c65689d331a94ef78196/4968a/001-sigmund-f0dJjQMhfXo-unsplash.jpg)<figcaption>"Photo by <a href="https://unsplash.com/@sigmund?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Sigmund</a> on <a href="https://unsplash.com/s/photos/settings?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a>"</figcaption>

🔔 This article was originally posted on my site, [MihaiBojin.com](https://MihaiBojin.com/application-settings/reading-application-settings-in-java?utm_source=DevTo&utm_medium=organic&utm_campaign=top-promo "MihaiBojin.com"). 🔔

* * *

For the past year, I've been on and off thinking of a common problem: handling properties in Java. While the problem seems simple, dealing with multiple sources, optionality, secrets, etc., is not trivial.

I started by looking for existing implementations, but I couldn't find many.

The closest I found was [Netflix's Archaius](https://github.com/Netflix/archaius/wiki/Overview), but it didn't do everything I needed and had features I didn't need. However, what sealed the deal was that the library seemed abandoned, with the last minor release having happened in 2019.

I decided to build my own ([#NIH](https://www.bmc.com/blogs/not-invented-here-syndrome/), I know 😝).

## [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#the-first-version)The first version

My first attempt resulted in the [props](https://github.com/mihaibojin/props) library. For this, I had a few goals.

I wanted the ability to **load properties from multiple sources** : [Java property files](https://docs.oracle.com/javase/tutorial/essential/environment/properties.html), [System properties](https://docs.oracle.com/javase/tutorial/essential/environment/sysprop.html), [OS environment variables](https://docs.oracle.com/javase/tutorial/essential/environment/env.html), etc.

Since these sources are text-based, the values are first loaded as strings. However, strings can be deserialized into many types, which is what the application would expect. Hence, we want such a library to type cast values into the appropriate (standard or user-defined) types. We could do that every time a value is read. However, doing so on every read would result in many unnecessary type conversions. A better approach is to cast once and memoize the typed value until and if it changes.

Apart from its value, **a _prop_ has other attributes (metadata)**. The metadata includes:

- if a _prop_ is required or optional
- if it has a default value
- if it represents a secret (in which case extra care needs to be taken)
- a description of what the property is used for, aiding with documentation

A key could be defined in more than one source, so the library **needs to determine which source owns which key**.

Then, the values could change at the source; to tackle that, we'd need a mechanism to check for updates and refresh any updated keys periodically.

We also want to account for **extendability**. For example, a client of this library might need to define new sources (e.g., read properties from a [MongoDB database](https://www.mongodb.com/) or an HTTP endpoint). To that end, we provide an interface that users can implement to add extra functionality.

Another use case is **managing secrets**. While it is best to use production-ready solutions (e.g., a [KMIP](https://en.wikipedia.org/wiki/Key_Management_Interoperability_Protocol)-based server), some applications require keys to be defined in property files. In that case, it is best to encrypt them at rest. Encrypting generates binary output; a common way to represent binary data as text (e.g., in a property file) is to base64-encode it. Our library would need to be able to deserialize a base64-encoded, encrypted value as a string seamlessly.

Since I wanted to use this library in Java projects, I set up a CD pipeline to release it to [Maven central](https://search.maven.org/artifact/com.mihaibojin.props/props-core/0.0.4/jar).

I have built [Props v1](https://props.mihaibojin.com/) with the above in mind.

## [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#the-architectural-problem)The architectural problem

However, I was too focused on building a proof of concept and didn't think too much about performance. I also built this first version with a static use-case in mind (the client is responsible for refreshing a _prop_'s value.)

There are, however, cases where a client would also benefit from being notified when values change. Upon realizing that, I added support for notifying subscribers of updates. I also started looking at where the bottlenecks were. While the library is by no means slow, a few original decisions make it difficult to improve.

This is a common problem in software engineering. For established libraries with significant user adoption, it is costly to rearchitect from scratch. Usually, the code would be updated slowly, taking great care to avoid breaking changes.

Since this is a personal project with no current production usage - I have a bit of flexibility.

I have decided to rewrite the code with performance in mind. However, I also want to focus on asynchronous primitives, which are a better choice for today's software.

Imagine the following scenarios:

**A.** A property is loaded once from a configuration file and used to configure the maximum number of requests allowed by the application in a given interval. When the application needs to be reconfigured, the file is updated, and the application restarted. Restarting is not instantaneous, and it can result in downtime for users. To avoid it, multiple instances need to be run and managed by an external orchestration service (e.g., Kubernetes).

**B.** The same property is aware of its origin and can notify the implementing code of any updates. The application can then reconfigure itself without fully restarting.

There is, of course, no 100% right solution. If a platform already manages the application, and multiple instances are deployed and running, and if restarting the service is a fast enough endeavor, Solution A may be perfectly viable. In most cases, however, at least having the option of using Solution B is a positive net benefit: it's there, but you don't have to use it. Not having it, though, could be limiting. This logic could be extended to replacing secrets, enabling a new feature for an increasing subset of users, etc.

## [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#how-would-a-better-implementation-look-like)How would a better implementation look like?

### [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#glossary-of-terms)Glossary of terms

Let's define a few common terms:

- **source** : where a key=value pair originates from
- **prop** : an object that can return a type cast value for its registered _key_
- **registry** : an object that keeps track of all **sources** and **props**
- **layers** : a mechanism that helps to establish the priority in which sources own a particular _key_
- **effective value** : the final value of a key, taken from the source that owns it

### [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#design-considerations)Design considerations

Let's outline a few design considerations.

Sources must be layered in the sense that they should establish **clear precedence over which source ultimately owns which key**.

When a _value_ is updated on a _source_, and that source owns the _prop_, the prop needs to be (eventually) updated with the new value. "Eventually" means that a prop may not see all the state transitions (writes) between reads. It's important to note that **I am not designing an event streaming solution**. Therefore, some updates may never reach the client.

We need to choose a **1:1 or 1:many mapping between keys and _prop_ objects** in the _registry_. On the one hand, allowing more than one prop for any given key could be flexible. For example:

```
var prop1 = new StringProp("my.key");
var prop2 = new StringProp("my.key");
```

Multiple callers could bind and use new _prop_ objects without any limitations. However, I believe this choice would enable users to write inefficient code.

The next question is, **should we allow _props_ of different types to be bound to the same _key_?**

Consider the following code:

```
var prop1 = new DurationProp("my.key");
var prop2 = new LongProp("my.key");
var prop3 = new StringProp("my.key");
```

You could argue that all three forms are needed, but the same could be achieved in the following way:

```
var prop = new DurationProp("my.key");
Duration result = prop.get();
Long seconds = result.toSeconds();
String stringValue = result.toString();
```

Asynchronous updates would need to be propagated fast. There is no point in implementing such a library only to support a few updates per second or only a few tens of keys defined in the system.

Let's focus on performance by having the library **restrict one _prop_ object per _key_** to keep the number of prop objects small and the implementation lean.

Since sources can specify custom update intervals, **we can assume values could change, and keys could appear or disappear** , on multiple sources, in quick succession.

Let's look at a few scenarios for a given _key_ defined on two sources:

| Action | Ownership | Value |
| --- | --- | --- |
| Prop is defined by source 1 | Source 1, val=1 | 1 |
| Prop is defined by source 2 | Source 2, val=2 | 2 |
| Prop is updated by source 1 | Source 2, val=3 | 2 |
| Prop is updated by source 2 | Source 2, val=4 | 4 |
| Prop is deleted from source 1 | Source 2 | 3 |
| Prop is defined by source 1 | Source 2, val=5 | 4 |
| Prop is deleted from source 2 | Source 1 | 5 |
| Prop is defined by source 2 | Source 2, val=6 | 6 |
| Prop is deleted from source 2 | Source 1 | 5 |
| Prop is deleted from source 1 | N/A | null |

Our implementation needs to handle all cases correctly. These could happen in fast succession for a large number of keys, so it's essential to handle these state transitions as efficiently as possible.

Some of them are easier than others; for example, updating a key's value without changing source ownership is straightforward. However, changing the source that owns a key is more involved since **we need first to determine the correct _source_ that should provide the _effective value_.**

There is a real possibility of **update storms** ; for example, a source could repeatedly own and disown a key over a short interval. This is probably more of an edge case than a legit need. In any case, the implementation should be able to:

- effectively deal with ownership transitions in quick succession
- flag when this behavior occurs so that a human operator can investigate the correctness

It's important to note that this case is different than everchanging values (e.g., a boolean flag that keeps flipping from true to false and back, or a counter that is incremented thousands of times per second.)

* * *

Another question is if **we should eagerly or lazily update each key?**

Even though several sources could potentially define thousands of key-value pairs, that doesn't necessarily imply that those values are always read or that they are refreshed at the same interval.

**Eagerly** establishing source-ownership and updating the _effective value_ of every key would probably be costly (performance-wise).

On the other hand, **lazily** determining which source owns each key at reading time, retrieving the _effective value_, and finally, type casting it would result in slower reads.

**The implementation will need an efficient way to keep track of _key_ ownership.**

For example, when a value is required, it would be best if the _registry_ could go directly to the _source_ that owns that key, instead of having first to find (iterate over all sources, in O(N) time) the appropriate source. Respectively, when a _source_'s values are updated, it also needs to efficiently publish updates to all _prop_ objects it owns while skipping ones it does not.

## [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#conclusion)Conclusion

I could write more, but for now, this article would have hopefully set the stage for what this library will do.

Rather than outlining every possible feature ahead of time, I prefer developing a series of articles as I get more and more into the code. Who knows, I may even change my mind about some of these things along the way!

I plan on (re)writing this Java library from scratch and documenting it all, including topics such as:

- setting up a GitHub repository
- configuring a build system
- configuring a CI/CD pipeline
- writing performant, well-tested code
- pushing releases to a public Maven repo (e.g., Maven Central)
- formatting the code to a common standard
- linting the code
- benchmarking and documenting a performance baseline
- and others

Stay tuned for more, and don't forget to [subscribe to my newsletter](https://motivated-founder-807.ck.page/4c5fb25380) if you want to receive all updates about this series by email!

Until next time...

Mihai