- The Configuration Component
The config component provides a Java API to load and process configuration properties from various sources into a
Configobject which the application can use to retrieve config data.
Maven Coordinates
To enable Config add the following dependency to your project’s pom.xml (see Managing Dependencies).
<dependencies>
<dependency>
<groupId>io.helidon.config</groupId>
<artifactId>helidon-config</artifactId>
</dependency>
</dependencies>Getting Started
Introducing the Config System
A brief overview of the config system helps clarify its different parts and how they work together. Most applications will typically deal with more than one of these parts.

These are the main parts of the configuration system:
Configsystem - allows you to read configuration data in an applicationA config source - a location containing configuration data (File, Map, Properties etc.)
A config parser - a component capable of transforming bytes into configuration data (such as JSON content, YAML etc.)
The Config system handles configuration data in an in-memory tree that represents the configuration structure and values.
This approach allows us to take any source data, be it a flat properties file or an object structure such as JSON, and transform it into a single tree that allows for overriding of values using heterogeneous config sources.
We are using the . as a separator of tree structure.
Example of two config sources that can be used by Config with the same data tree in different formats:
A Properties source:
web.page-size=25A YAML source:
web:
page-size: 25The configuration has the same internal representation in Config and can be accessed using the Config API as follows:
int pageSize = config.get("web.page-size")
.asInt()
.orElse(20);Or using the tree node approach:
int pageSize = config
.get("web")
.get("page-size")
.asInt()
.orElse(20);For this first example we can see the basic features of Config:
Configuration is a tree of
ConfignodesYou can use
.as a tree separator when requesting node valuesEach config value can be retrieved as a typed object, with shortcut methods for the most commonly used types, such as
int,String,longand otherYou can immediately provide a default value for the cases the configuration option is not defined in any source
Overriding Values
The Config system treats config sources as a hierarchy, where the first source that has a specific configuration key "wins" and its value is used, other sources are not even queried for it.
For example the default configuration when you use Config.create() uses the following config sources:
- System properties config source
- Environment variables config source
- A classpath config source called
application.?where the?depends on supported media types currently on the classpath. By default it isproperties, if you have YAML support on classpath, it would beapplication.yaml(aConfigParsermay add additional supported suffixes for default file)
Let’s consider the following keys:
- System property
answer=42 - Environment variable
ANSWER=38 - A key in a configuration file
answer=36
When you request config.get(`answer).asInt().orElse(25), you would get `42
This allows you to configure environment specific configuration values through system properties, environment variables, or through files available on each environment (be it a physical machine, a Kubernetes pod, or a docker image) without changing your source code.
Built-in Support for Config Formats
If you add additional Helidon config maven artifacts to your dependencies, then the config system can read formats other than Java properties format and the default configuration will search for other application file types in the following order. Note that the default configuration stops once it finds one of the files below; it does not merge all such files it can find.
| Source | Helidon maven artifact ID (group ID: io.helidon.config) | Notes |
|---|---|---|
application.yaml | helidon-config-yaml | YAML format http://yaml.org |
application.conf | helidon-config-hocon | HOCON format https://github.com/lightbend/config#using-hocon-the-json-superset |
application.json | helidon-config-hocon | JSON format https://json.org/ |
application.properties | helidon-config | Java properties format |
Config Filters
Config system applies configured config filters on each value when it is requested for the first time.
There is a built-in filter called ValueResolvingFilter (enabled by default, can be disabled through API) that resolves references to other keys in values in configuration.
Example: Let’s consider the following example properties file
host=localhost
first-service.host=${host}/firstservice
second-service.host=${host}/secondserviceThe filter resolves the ${host} reference to the localhost value.
This makes it easier to override values in testing and production, as you can just override the host key and leave the URIs same.
Change Support
Config is an immutable in-memory tree. Nevertheless we know that configuration sometimes changes, and we may want to react to such changes.
In Config system, you can do this through change support provided by these components:
Config.onChange()API - you can use to add your listener, to be notified of configuration changesPollingStrategy- a component providing regular events to check if a source has changed. This requires support in config sources themselves (seePollableSource)ChangeWatcher- a component watching the underlying source for changes. This requires support in config sources themselves (seeWatchableSource)EventConfigSource- an event source that is capable of notifying about changes iteslf
If you want to receive onChange events, you must configure your Config with at least one source that is capable of providing changes (having a PollingStrategy or ChangeWatcher configured, or implementing EventConfigSource)
Typed config values
The Config object lets your application retrieve config data as a typed ConfigValue.
You can retrieve a ConfigValue<T> using the following as methods in Config: * asString() - to get a string config value * asBoolean() and other accessors for primitive types * as(Class) - to get a value for a type that has a mapper configured * as(Generic) - to get a value for a type supporting generics (such as Set<String>) * asMap() - to get a map of key to value pairs * asList(Class) - to get a list of typed values * as(Function<Config,T>) - to get a typed value providing a mapper function
ConfigValue<T> can be used to obtain: * an Optional<T> value from a single node, * the T value from a single node interpreted as a basic Java type (primitive or simple object) already known to the config system (such as a boolean or a Double), or * a complex Java type from a subtree of the config tree.
+ The config system automatically knows how to return List and Map complex types, and you can provide config mappers to convert a config subtree to whatever Java types your application needs.
Next Steps
Although the default configuration is very simple to use, your application can take as much control as it needs over
loading configuration data,
accessing the data once loaded, and
extending and modifying the behavior of the config system.
You do this by:
creating and invoking methods on a
Config.Builderobject to construct aConfiginstanceUsing a builder, the application can control everything about how the config system creates the resulting
Configinstance: config sources, parsers, polling strategy, filters, overrides, mappers, whether or not environment variables and Java system properties serve as config sources. The JavaDoc explains how to use theConfig.Builder.using a config profile to choose the sources to be used
creating a meta-configuration file on the runtime classpath or file system to control how the config system prepares the default configuration.
Once created, the Config object provides many methods the application can use to retrieve config data as various Java types. See the Config JavaDoc for complete details.
The links in the following tables lead you to more information about various other config topics.
| Topic | Documentation |
|---|---|
| Where config comes from | Config sources,Config Profiles, meta-configuration |
| What format config data is expressed in | Config parsers, supported formats |
| How to filter, override, and dereference values | Filters and overrides |
| What happens when config data changes | Config polling |
| How to deal with loading errors | Config retry policies |
| Topic | Documentation |
|---|---|
| How config data is translated into Java types | Config mappers |
| How to navigate config trees | Navigation |
| Topic | Documentation |
|---|---|
| Writing extensions | Extensions |