Search

Dark theme | Light theme

October 17, 2024

Helidon SE Helpings: Default Configuration Sources

When we use Helidon SE we can use the Config class to pass configuration properties to our application. The static method create() creates a default configuration. The Config class is then configured to support different input sources. This configuration reads configuration properties from the following sources in order:

  1. Java system properties,
  2. system environment variables,
  3. a file on the classpath that has the name application.properties (based on default config parser that is part of the artifact helidon-config).

The last input source behaves differently based on which classes that can parse a configuration file are on the classpath of our application. If we use the helidon-config artifact on the classpath then the configuration file read is application.properties. To read a JSON formatted configuration file we must add the helidon-config-hocon artifact to the classpath. The file that is read is application.json. With the same artifact we can read a HOCON formatted configuration file that is named application.conf. Finally if we add the helidon-config-yaml artifact to the classpath we can read a YAML formatted configuration file that is named application.yaml or application.yml. Helidon SE will only read one configuration file from the classpath with the following order of preference:

  1. application.yaml or application.yml,
  2. application.conf,
  3. application.json,
  4. application.properties.

In the following example class we create a default configuration using Config.create() and we show the contents of the configuration property app.message:

// File: src/main/java/mrhaki/helidon/Application.java
package mrhaki.helidon;

import io.helidon.config.Config;

public class Application {

    public static void main(String[] args) {
        // Create the default configuration.
        // Configuration properties are read from in order:
        // - from Java system properties
        // - from system environment variables
        // - from a file on the classpath that has the name
        //   'application.properties' (based on default config
        //   parser that is part of the artifact helidon-config).
        Config config = Config.create();

        // Get the configuration property app.message.
        // If the property is not set, the fallback value
        // is defined as "Hello from application code".
        String message = config.get("app.message")
                               .asString()
                               .orElse("Hello from application code");

        // Print the value of the configuration property to System.out.
        System.out.printf("app.message = %s%n", message);
    }
}

In our pom.xml we first only have the dependency for the artifact helidon-config:

...
<dependencies>
    <dependency>
        <groupId>io.helidon.config</groupId>
        <artifactId>helidon-config</artifactId>
    </dependency>
</dependencies>
...

Let’s build our application and run it without any configuration properties and rely on the default value that we defined in our code:

$ helidon build
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Detecting the operating system and CPU architecture
[INFO] ------------------------------------------------------------------------
[INFO] os.detected.name: osx
[INFO] os.detected.arch: x86_64
[INFO] os.detected.version: 15.0
[INFO] os.detected.version.major: 15
[INFO] os.detected.version.minor: 0
[INFO] os.detected.classifier: osx-x86_64
[INFO]
[INFO] -----------------------< mrhaki.helidon:config >------------------------
[INFO] Building config 0.0.0-SNAPSHOT
[INFO]   from pom.xml
...

$ java -jar target/config.jar
app.message = Hello from application code

Next we add the file application.properties to the directory src/main/resources. This will put the file in the JAR file we build and make it available on the classpath:

# File: src/main/resources/application.properties
app.message=Hello from 'application.properties'

When we build and run our application again we see that the value of the configuration property app.message is read from the file application.properties on the classpath:

$ helidon build
...

$ java -jar target/config.jar
app.message = Hello from 'application.properties'

Our code also support setting the configuration property using environment variables. The value set by the environment variable APP_MESSAGE will overrule the value found in application.properties:

$ APP_MESSAGE="Hello from environment variable" java -jar target/config.jar
app.message = Hello from environment variable

We can overrule the value of the environment variable by setting the configuration property using the Java system properties:

$ APP_MESSAGE="Hello from environment variable" java -Dapp.message="Hello from Java system property" -jar target/config.jar
app.message = Hello from Java system property

If we replace the artifact helidon-config with helidon-config-hocon we can read a file named application.json from the classpath. First we change our dependency in the pom.xml:

...
<dependencies>
    <dependency>
        <groupId>io.helidon.config</groupId>
        <artifactId>helidon-config-hocon</artifactId>
    </dependency>
</dependencies>
...

Next we add the file application.json in src/main/resources:

{
  "app": {
    "message": "Hello from 'aplication.json'"
  }
}

We can rebuild our application and run it to see the following output:

$ helidon build
...

$ java -jar target/config.jar
app.message = Hello from 'aplication.json'

Instead of a JSON file we can also use file with the extension .conf written in HOCON format. The following example file application.conf in src/main/resources sets the configuration property app.message:

// File: src/main/resources/application.conf
app {
    message = Hello from 'application.conf'
}

When we build and run our application we see the following output:

$ helidon build
...

$ java -jar target/config.jar
app.message = Hello from 'application.conf'

To support a configuration file with the name application.yaml or application.yml in YAML format we must add the artifact helidon-config-yaml as dependency:

...
<dependencies>
    <dependency>
        <groupId>io.helidon.config</groupId>
        <artifactId>helidon-config-yaml</artifactId>
    </dependency>
</dependencies>
...

Our example application.yaml will look like this:

# File: src/amin/resources/application.yaml
app:
  message: Hello from 'application.yaml'

For the final time we build and run the application to show the output:

$ helidon build
...

$ java -jar target/config.jar
app.message = Hello from 'application.yaml'

Written with Helidon SE 4.1.2.