Managing configurations in cloud-native Java applications can be complex. Developers often juggle multiple environments—local, development, testing, and production—each with its own set of properties.

This complexity can lead to errors, inconsistencies, and a significant amount of manual effort.

Keeping track of database credentials, feature flags, and other settings across these environments is a common challenge that can slow down development and introduce risks.

A robust configuration management strategy is essential for building scalable and maintainable applications.

The right approach centralizes settings, simplifies updates, and ensures that each environment loads the correct properties automatically.

This not only streamlines the development workflow but also enhances the security and reliability of your application.

This post explores a modern solution for handling Java configuration in a cloud native context. We will introduce Avaje Config, a lightweight library designed to simplify this entire process.

You will learn how to set up and use Avaje Config to manage your application’s properties efficiently, making your development lifecycle smoother and more predictable.

The Challenge of Traditional Configuration

In traditional Java applications, managing configuration often involves using multiple properties files.

A typical setup might include application.properties for shared defaults, application-dev.properties for development, and application-prod.properties for production. While this approach works, it presents several difficulties.

Drawbacks of Multiple Files

  • Complexity: As the number of environments grows, so does the number of property files. This can quickly become unwieldy and difficult to manage.
  • Redundancy: Common properties are often duplicated across files, making updates tedious and prone to error. A change in one file might need to be replicated in several others.
  • Inconsistency: It is easy to introduce inconsistencies between environments, leading to unexpected behavior and bugs that are hard to track down.

Manual Management Issues

Manually switching between configuration files or using build profiles to manage settings is a common practice. However, this method is prone to human error.

Developers might forget to switch profiles, leading to the wrong configuration being loaded.

This can cause anything from minor issues in a local test to major outages in production. Automating this process is key to building reliable systems.

Introducing Avaje Config

Avaje Config is a small, dependency-free Java library that offers a streamlined approach to configuration management.

It is designed with cloud-native principles in mind, providing a simple yet powerful way to handle application properties.

It automatically detects the current environment and loads the appropriate configuration, eliminating the need for manual intervention or complex build scripts.

Core Principles

  • Convention over Configuration: Avaje Config follows sensible defaults, minimizing the amount of setup required. It automatically looks for standard properties files like application.properties and application.yml.
  • Environment Detection: The library intelligently identifies the runtime environment by checking system properties, environment variables, or specific file indicators.
  • Layered Configuration: It merges properties from multiple sources, allowing you to override defaults with environment-specific settings cleanly.

Getting Started

To begin using Avaje Config, you only need to add its dependency to your project.

Maven Dependency:

<dependency>

 <groupId>io.avaje</groupId>

 <artifactId>avaje-config</artifactId>

 <version>3.1</version>

</dependency>

With this single addition, you are ready to simplify your Java configuration workflow.

Environment-Aware Configuration Loading

One of the standout features of Avaje Config is its ability to automatically load the correct properties based on the runtime environment.

This is achieved by following a simple and predictable loading order, which allows for a clear hierarchy of settings.

Loading Order

Avaje Config searches for and loads properties in the following sequence:

  1. application.properties / application.yml: The base configuration file containing default values.
  2. application-{environment}.properties / application-{environment}.yml: Environment-specific files that override the base settings.
  3. External Properties: Properties files located outside the classpath, specified via the load.properties system property.
  4. System Properties: Any properties defined as Java system properties (-Dkey=value).

Example Setup

Imagine you have two configuration files in your src/main/resources directory:

  • application.properties:
    app.name=My Cool App
    database.url=jdbc:h2:mem:main
  • application-test.properties:

e app.name=My Test App
database.url=jdbc:h2:mem:test
“`
When you run your application, Avaje Config loads application.properties first. If you then specify the test environment by setting the system property -Denv=test, it will also load application-test.properties.

The properties in the test file will override the base ones, so app.name will be “My Test App.”

Advanced Configuration Techniques

Avaje Config provides more than just basic property loading. It includes several advanced features that give you greater flexibility and control over your application’s configuration.

Reading Properties

You can easily access configuration values using the static methods on the Config class.

Example:

// String property

String appName = Config.get(“app.name”);

 

// With default value

int port = Config.getInt(“app.port”, 8080);

 

// Boolean property

boolean featureFlag = Config.getBool(“feature.new.enabled”, false);

These methods provide type-safe access to your properties, with the ability to specify default values to prevent errors when a property is missing.

Dynamic Property Changes

Avaje Config supports dynamic reloading of properties. You can modify properties at runtime and have the changes reflected in your application without a restart.

This is particularly useful for toggling feature flags or updating settings on the fly. To listen for changes, you can register a Configuration.ChangeListener.

Integrating with Kubernetes and Docker

In a cloud native architecture, applications often run inside containers orchestrated by platforms like Kubernetes.

Avaje Config is well-suited for these environments, as it can seamlessly read configuration from environment variables and mounted files.

Using Environment Variables

You can pass configuration to your Docker container using environment variables. Avaje Config automatically picks them up. For example, in a Kubernetes deployment file:

env:

 – name: DATABASE_URL

   value: “jdbc:postgresql://prod-db:5432/main”

The library maps DATABASE_URL to database.url by convention, making it accessible via Config.get(“database.url”).

YAML Support

For more complex configurations, Avaje Config also supports YAML files. This allows you to structure your properties hierarchically, which can be more readable for nested settings.

Simply add the avaje-config-yaml dependency to your project, and the library will automatically detect and parse application.yml files.

Unlock Simpler Configuration Today

Managing configurations across different environments is a fundamental challenge in modern software development. Traditional methods are often manual and error-prone, but they don’t have to be.

By adopting a modern tool like Avaje Config, you can automate environment detection and create a clear, layered approach to your Java configuration.

Its convention-over-configuration model, combined with powerful features like dynamic reloading and cloud-native integration, streamlines the entire process.

This simplification allows developers to focus more on building features and less on managing settings.

If you are building cloud native Java applications, consider integrating Avaje Config to make your development lifecycle more efficient and reliable.

Ready to take control of your application’s configuration? Explore the Avaje Config documentation to get started.