Loaders & Load Order

The order AndHow uses to scan configuration sources for property values, and the Loaders used to load from each source.

Default configuration source loading order

The default order AndHow scans configuration sources for Property values is listed below. Property values are set on a first win basis, so the first, non-null value found for a Property will be its value.

  1. Fixed Values - Values set in code during initiation

  2. Arguments passed to main(String[] args)

  3. System Properties

  4. Environmental Variables

  5. JNDI values

  6. Properties file on the filesystem (path requires configuration)

  7. Properties file on the classpath (defaults to /andhow.properties)

This is just the default source load order, but it works for most applications. Its easy to change the load order or add custom loaders.

Configuration sources and the Loaders that load them

Each configuration source is handled by a different Loader class, each of which has slightly different behaviours related to the source it is reading from.

Fixed Values - Values set in code during initiation

Loaded by: StdFixedValueLoader

The fixed value loader is used to set values directly in code.

Typical Use Case

Since this loader receives values directly assigned from your code, it is only useful for creating application test configurations. Configuration values can be set directly prior to running a test so an application can be tested in a specific configured state. Since this is the first loader, a property value set by this load will override configuration values found by any other loader.

Basic Behaviors

  • Trims String values: No - Since values are set in code, white-space is assumed to be correct

  • Complains about unrecognized properties: Yes - See code example below

Loader Details and Configuration

One simple way to set fixed values is shown below. AndHow will discover this class implementing the AndHowInit interface during initialization to read your configuration:

import org.yarnandtail.andhow.*;

public class SetFixedValues implements AndHowTestInit {
    @Override
    public AndHowConfiguration getConfiguration() {
        return AndHow.findConfig()
            .addFixedValue(MY_PROP, "some value")
            .addFixedValue("org.myapp.MyClass.PhaserLevel", "Stun");
    }
}

The code above is an example of an AndHowTestInit, which is auto-discovered at startup and used to configure AndHow in a test environment (there is also an AndHowInit for production). Both calls to addFixedValue() are handled by the StdFixedValueLoader, which will complain if it cannot find a property with the name org.myapp.MyClass.PhaserLevel.

Another place fixed values could be added is at an application entry point, such as the main method.

TODO: Link to more details about AndHowInit and AndHowTestInit.

Alternatively you can use AndHow.findConfig() at an application entry point, such as the main method.

TODO: Link to main method example.

Arguments passed to main(String[] args)

Loaded by: StdMainStringArgsLoader

Reads an array of Strings containing key value pairs in the form key=value, and parses & loads the value for any key that matches a Property name.

Typical Use Case

A single class, executable jar or desktop application that accepts command line arguments to the public void main(String[] args) method can pass them on to AndHow. This loader scans the key=value pairs and parses values from the keys that match application Properties.

Basic Behaviors

  • Trims String values: Yes - Leading and trailing white space is removed from all values

  • Complains about unrecognized properties: No - Other properties can be passed in on command line, so the loader does not throw an error if doesn't recognize a property name.

Loader Details and Configuration

AndHow has no way to intercept command line arguments, so the application code needs to help a bit, like this:

import org.yarnandtail.andhow.*;

public class MyAppClass {
    public static void main(String[] args) {
        AndHow.findConfig().setCmdLineArgs(args);
        // ...other application code
    }
}

The code above passes the command line arguments to AndHow. The main method is an application entry point. Its the first application code to run, so its safe to configure AndHow. When the first Property value is read, AndHow will initialize itself from its configuration and will block any further attempts to call AndHow.findConfig() by throwing an error. Another example of an entry point would be a lambda handler() method.

Running a Java application from command line and passing main arguments generally looks like this:

java -jar [jar name] [Arguments passed to the main method]

AndHow property values are passed as name=value pairs to the main method, using either full canonical property names or aliases, e.g.:

java -jar MyApp.jar full.name.of.PROPERTY=aValue propAlias=aValue

This loader has special handling for FlagProp's allowing them to be set true just by including their name or alias, e.g.:

java -jar MyApp.jar enableAmazing

If there is a FlagProp with the alias 'enableAmazing', just including its full name or alias would set it true, the equivalent of including enableAmazing=true.

System Properties

Loaded by: StdSysPropLoader

Reads Java system properties and parses & loads the value for any key that matches a Property name.

Typical Use Case

An application might receive all or some of its configuration from Java system properties that are set when the JVM starts. Java system properties can be set in a startup script, which could be customized for each environment. This provides a relatively easy way for deployment automation or sys admins to control application configuration values across many servers.

Basic Behaviors

  • Trims String values: Yes (0.5.0 and later) (No 0.4.2 and earlier)

  • Complains about unrecognized properties: No - Since other properties can be in the list, AndHow cannot assume all the system property must match known properties.

Loader Details and Configuration

This loader loads properties from java.lang.System.getProperties(). Over the lifecycle of the JVM, values of system properties can change so this loader is working from a snapshot of the system properties it finds at the time of AndHow initialization. Once loaded, AndHow property values never change.

For FlgProp properties (true/false flags), the StdSysPropLoader will set the Property's value to true if a matching environment variable is found, even if the value of the property is empty. System properties can be cleared via java.lang.System.clearProperty(name), which is how a flag value could be unset prior to AndHow loading.

Passing system properties on command line looks like this:

java -Dfull.name.of.MY_PROPERTY=someValue -jar MyJarName.jar

Environmental Variables

Loaded by: StdEnvVarLoader

Reads the operating system defined environment variables and parses & loads the value for any key that matches a Property name.

Typical Use Case

An application might receive all or some of its configuration from OS defined environmental variables that are passed to the JVM when the JVM starts. Environment vars can be set in the OS and augmented in a startup script, which could be customized for each environment. Similar to Java system properties, this provides an easy way for deployment automation or sys admins to control application configuration values across many servers.

Environment vars are becoming the standard way to configure applications since many applications run in virtualized environments, and 'Twelve Factor' has codified their use.

Basic Behaviors

  • Trims String values: Yes (0.5.0 and later) (No 0.4.2 and earlier)

  • Complains about unrecognized properties: No - Since other environment vars can be in the list, AndHow cannot assume all the vars must match known properties.

Loader Details and Configuration

This loader loads values from System.getenv(). Those environmental values are provided by the host environment (the OS) as a static snapshot to the JVM at startup as a String-to-String map. The underlying OS environment variables may change, however, the JVM will be unaware of it. Similarly, AndHow property values never change once loaded.

For FlgProp properties (true/false flags), the StdEnvVarLoader will set the Property's value to true if a matching environment variable is found, even if the value of the property is empty.

The Windows OS uses ALL CAPS for environment variables, while all others OS's are case sensitive - This is the primary reason AndHow is case insensitive by default. Each OS has a different way to set an environmental variables.

JNDI values

Loaded by: StdJndiLoader

Attempts to look up the name of each application Property in the JNDI environment and load the value for any that are found.

Typical Use Case

A web service or application that runs in an application container such as Tomcat. Application containers provide a JNDI environment which can be used to configure applications running in their environment.

Basic Behaviors

  • Trims String values: No - JNDI values are usually configured in XML and have associated type information. It can be assumed that white space on a string is intentional.

  • Complains about unrecognized properties: No (Actually NA - see below)

Unique Behaviors

  • Complains about missing JNDI environment: No - (by default) AndHow can detect when there is no JNDI context and will silently stop looking for JNDI values.

  • Is case sensitive: Yes - This is one of the only loaders that is case sensitive. See discussion below.

Loader Details and Configuration

While most Loaders process a configuration resource entirely (e.g. a properties file), the JNDI loader works the other way: It goes through the list of known Properties attempts to look up each property name in the JNDI context. Since JNDI is case sensitive, the JNDI Loader is case sensitive as well, since it must individually probe the context for each value. (Its just not possible to fetch all registered names from the entire JNDI context)

JNDI implementations vary in how they name properties, so the JNDI loader will try several common name forms, for example, the JNDI loader will attempt to look up the following JNDI names for a property named org.foo.My_Prop:

  • java:comp/env/org/foo/My_Prop

  • java:comp/env/org.foo.My_Prop

  • java:org/foo/My_Prop

  • java:org.foo.My_Prop

  • org/foo/My_Prop

  • org.foo.My_Prop

AndHow will also look for all Property 'inAliases' as well. The list of six name forms comes from three root forms and two name forms. AndHow looks for three different roots (the part that comes before the variable name):

  • java:comp/env/ is used by Tomcat and several other application servers

  • java: (and nothing else) is used by some non-container environments

  • [no root] Glassfish (and possibly others?) uses no root at all

The two name forms are:

  • dot.separated.AndHow.style.names

  • slash/separated/JNDI/style/names

AndHow will throw an error at startup if it finds multiple names in the JNDI context that refer to the same property.

Specifying JNDI environment variables varies by environment, but here is an example of specifying some properties in a Tomcat context.xml file:

<Context>
. . .
<Environment name="org/simple/GettingStarted/COUNT_DOWN_START" value="3" type="java.lang.Integer" override="false"/>
<Environment name="org/simple/GettingStarted/LAUNCH_CMD" value="GoGoGo!" type="java.lang.String" override="false"/>
. . .
</Context>

In the example above, Tomcat will automatically prepend java:comp/env/ to the name it associates with each value. As the example shows, JNDI values can be typed. If AndHow finds the value to already be the type it expects (e.g. an Integer), great! If AndHow finds a String and needs a different type, AndHow will do the conversion. Any other type of conversion (e.g. from a Short to an Integer) will result in an exception.

If your JNDI environment uses a non-default different root, it can be added using one of the built-in Properties for the JNDI loader. Those property values would need to be loaded prior to the JNDI loader, so using system properties, for example, would work. Here is an example of adding the custom JNDI root java:xyz/ as a system property on command line:

java -Dorg.yarnandtail.andhow.load.std.StdJndiLoader.CONFIG.ADDED_JNDI_ROOTS=java:xyz/ -jar MyJarName.jar

Properties file on the filesystem

Loaded By: StdPropFileOnFilesystemLoader

Parses and loads Properties from a Java .property file on the file system. Since file systems vary, there is no default filepath that AndHow attempts to load from.

Typical Use Case

A web application running in a web container might load some or all of its configuration from a properties file on the file system. The properties file is not part of the application, so it survives redeployments. A single environmental or system property could then be used to specify the path to the properties file.

This is a non-standard way to load configuration, but is used by some applications.

Basic Behaviors

  • Trims String values: Yes

  • Complains about unrecognized properties: Yes

  • Complains if the .properties file is missing: Yes, but only if a file path is configured

Unique Behaviors

  • This loader requires configuration to be activated - it has no default file path that it attempts to load from.

  • If there are duplicate property entries in a properties file, the last value is used and the others ignored. This is the behaviour of java.util.Properties, which silently ignores duplicate property entries. Full details can be found in the properties file specification.

Loader Details and Configuration

This loader is only active if it is configured as shown below, or similar:

import org.yarnandtail.andhow.*;
import org.yarnandtail.andhow.property.StrProp;

public class UsePropertyFileOnFilesystem implements AndHowInit {
    public static final StrProp MY_FILEPATH = StrProp.builder()
    .desc("Path to a properties file on the file system. " +
    "If a path is configured, startup will FAIL if the file is missing.").build();


    @Override
    public AndHowConfiguration getConfiguration() {
        return AndHow.findConfig()
            .setFilesystemPropFilePath(MY_FILEPATH);
    }
}

The code above adds the property MY_FILEPATH (the name is arbitrary) which is used to configure the StdPropFileOnFilesystemLoader with a file location. When AndHow initializes, the StdPropFileOnFilesystemLoader checks to see if a value has been loaded for MY_FILEPATH by any prior loader. If a value is present, the loader tries to load from the configured file system path. If no value is configured, this loader is skipped.

Properties file on the classpath (defaults to /andhow.properties)

Loaded by: StdPropFileOnClasspathLoader

Parses and loads Properties from a Java .property file on the classpath. By default, this loader will look for a file named andhow.properties at the root of the classpath.

Typical Use Case

A service application might load the majority of its configuration from system properties or environmental variables, however, some sane default configuration values can be bundled with the application. By default, AndHow will discover and load a file named andhow.properties.

Basic Behaviors

  • Trims String values: Yes

  • Complains about unrecognized properties: Yes

  • Complains if the andhow.properties file is missing: No

Unique Behaviors

  • If there are duplicate property entries in a properties file, the last value is used and the others ignored. This is the behaviour of java.util.Properties, which silently ignores duplicate property entries. Full details can be found in the properties file specification.

Loader Details and Configuration

Configuring the name or classpath of the properties file can be used to enable different configuration profiles based on the environment. For instance, a system property could specify that /test.properties be used on a test server and /production.properties on a production server. An example of configuring the property file path:

// Some import org.yarnandtail.andhow.*;
import org.yarnandtail.andhow.property.StrProp;

public class UsePropertyFileOnClasspath implements AndHowInit {
    public static final StrProp MY_CLASSPATH = StrProp.builder()
    .desc("Path to a properties file on the classpath. "
    + "If the file is not present, it is not considered an error.").build();


    @Override
    public AndHowConfiguration getConfiguration() {
        return AndHow.findConfig()
            .setClasspathPropFilePath(MY_CLASSPATH);
    }
}

The code above adds the property MY_CLASSPATH (the name is arbitrary) which is used to configure the StdPropFileOnClasspathLoader with a custom property file location. When AndHow initializes, the StdPropFileOnClasspathLoader checks to see if a value has been loaded for MY_CLASSPATH by any prior loader. If a value is present, the loader tries to load from the configured classpath. If no value is configured, the default classpath is assumed.

Last updated