Core Java

Set it up

In Java, we often have framework support for importing settings from the file system of our application. If we’re lucky, and we often are, these settings can be customised and overridden by system properties or environment variables.

However, there are a couple of situations where this doesn’t quite apply:

  • Very lightweight applications that use no frameworks
  • Loading custom settings based on business logic

Though we can shoe-horn heavier frameworks like Spring into the first, or try to force Spring to process properties for us, often we need a lighter solution.

Lightweight Config

I recently wrote and released Lightweight Config, an open source package to solve this with either .yaml or .properties files.

I’ve demonstrated its use in AWS Lambdas in an article on Baeldung.com.

I thought it might be nice to cover a different use case in this article, notably how it might be used to load settings up in a test.

At The Max

I wrote Lightweight Config from the ground up, but I’ve used its predecessors extensively. Originally, it was a test-helper library. Then I created one for loading settings for lambdas.

At full strength, you’d define a .yml file:

1
2
3
4
5
6
7
hardCoded: true
interpolated: ${SOME_ENV_VAR:-default}
partialInterpolation: Welcome to ${APP_NAME}
database:
   url: ${DB_URL}
   username: ${DB_USER}
   password: ${DB_PASSWORD}

Then a POJO to load the file into:

1
2
3
4
5
6
7
8
public class Settings {
    private boolean hardCoded;
    private String interpolated;
    private String partialInterpolation;
    private DatabaseSettings database;
 
    // getters and setters
}

Then it’s a one liner to load from the yaml into the Settings object – Settings settings = ConfigLoader.loadYmlConfigFromResource("settings.yaml", Settings.class)

There are also some hooks that can be applied to plug in custom tags if necessary.

Reading Per Environment Properties

Let’s flip to an example where we just want some Java .properties loaded into Properties. One might argue that the POJO approach gives us a better API, but let’s say we’re using something that’s already bound to Properties, such as an email client, or DB connection pool.

Here’s a snippet of some settings that relate to dev:

1
2
3
workers=12
sourceEmail=test@mytest.com
pdfFolder=/home/test/pdf

Let’s call this file profiles/dev.properties.

Now let’s create a parent file with all the global settings in:

1
2
3
4
5
6
#import profiles/${ENV_NAME}.properties
 
threadPoolSize=24
versionNumber=${BUILD_VERSION:-Unknown}
adminUser=admin
adminPassword=${ADMIN_PASSWORD}

Let’s call this file app.properties and put it in the same directory as contains the profiles directory mentioned above.

Now we can load both the above files into a Properties object by:

1
2
Path appPropertiesPath = PROPERTIES_DIR.resolve("app.properties");
Properties properties = ConfigLoader.loadProperties(appPropertiesPath);

What happens in this case is that the various placeholders are filled in from environment variables (or system properties if you prefer). Included in this is the #import statement, which not only describes how a child file is imported, but allows placeholder interpolation into the path of that file.

So, by setting a different ENV_NAME environment variable, the same loading code could import a different set of per-environment properties into the whole Properties object being loaded.

It’s a simple syntax/approach that’s flexible enough to use for a variety of things.

I hope it’s useful.

Published on Java Code Geeks with permission by Ashley Frieze, partner at our JCG program. See the original article here: Set it up

Opinions expressed by Java Code Geeks contributors are their own.

Ashley Frieze

Software developer, stand-up comedian, musician, writer, jolly big cheer-monkey, skeptical thinker, Doctor Who fan, lover of fine sounds
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button