# Configuring AndHow

Why would an application need to configure AndHow? There are several possible reasons:

* To pass in command-line arguments
* To use a custom name for the classpath andhow\.properties file
* To use a properties file on the filesystem (non-classpath), which requires configuring a file path
* To add, remove or reorder the loaders that load Property values, or configure them
* To set fixed values for some Properties (mostly done for testing)

### AndHow Configuration can only happen before initialization <a href="#h.9yf27fod3dww" id="h.9yf27fod3dww"></a>

AndHow ensures that its state and Property values are immutable once [initialized](https://www.andhowconfig.org/user-guide/andhow-initialization), so any attempt to modify AndHow's configuration after initialization results in a RuntimeException.  How can you be sure your code to configure AndHow happens before initialization?

### The `AndHow.findConfig()` method

`AndHow.findConfig()` is the only way to access the configuration AndHow uses for itself.  Until [initialization](https://www.andhowconfig.org/user-guide/andhow-initialization), AndHow holds a reference to an `AndHowConfiguration` instance that can be retrieved via `AndHow.findConfig()`.  All configuration happens via the `AndHowConfiguration` instance, and after initialization the reference is gone.

The first time `findConfig()` is called, AndHow scans the classpath for a class implementing `AndHowInit` (or `AndHowTestInit`).  If an implementation exists, it's `getConfiguration()` method is called to provide the `AndHowConfiguration` instance.  If no AndHowInit class exists, AndHow starts with a default `StdConfig` instance.  Later calls to `findConfig()` return the same instance that was found or created in the first call.

As a first step of initialization, AndHow calls `findConfig()` on itself so it initializes with the configuration that has been built up, created by default, or returned from the `AndHowInit` class.

### Configuring AndHow at a well defined entry point

The simplest way to ensure AndHow configuration happens before Properties are accessed is to have a well defined [Entry Point](https://en.wikipedia.org/wiki/Entry_point).  Common well defined entry points are:

* The main method of application startup class
* The `ServletContextListener.contextInitialized` method in a Servlet application
* The `handle()` method of a lambda function
* Any well documented init method that is invoked prior to all other application code

Generally a deployed application of GUI will have a well defined entry point, while a reusable utility library will not.

### Configuration via the `AndHowInit` interface

AndHow will discover and use a class implementing `AndHowInit` to configure itself, if it is present, so implementing that interface in your deployable application is the best way to configure AndHow.  It ensures your configuration is always used and won't attempt to configure AndHow 'late', after it is already initialized.  Example:

```java
public class InsertLoader implements AndHowInit {

	@Override
	public AndHowConfiguration getConfiguration() {
		PropFileOnClasspathLoader pfl = new PropFileOnClasspathLoader();
		pfl.setFilePath("/my.properties");
		
		return AndHow.findConfig()
			.insertLoaderBefore(StdJndiLoader.class, pfl);
	}
}
```

This example implements the `AndHowInit` interface to add a new Loader to load "my.properties" from the classpath before the JNDI loader.  No other code is required - AndHow will find this class during its [initialization process](https://www.andhowconfig.org/user-guide/andhow-initialization) and use the new loader.

{% hint style="info" %}

#### Best Practice:  Use an AndHowInit class to configure AndHow and include it with your deployable application, not a library or dependency

{% endhint %}

Only a single `AndHowInit` class is allowed on the classpath, otherwise configuration would be ambiguous. Thus, don't bundle an AndHowInit class with a distributable library - it is only intended to be used with deployable apps.

{% hint style="info" %}
If `AndHow.findConfig()` calls `AndHowInit.getConfiguration()`, doesn't it cause a loop when `findConfig` is used inside that method??

Well, sure.  Yes it would.  To keep the API simple and make `findConfig` the universal way to access configuration, AndHow detects the re-entrant call to findConfig and simply returns a new StdConfig.
{% endhint %}

### Setting command line arguments

This is a common need and appears in so many examples that its easy to miss that this is actually an example of configurating AndHow.

AndHow can load values from most configuration sources automatically, however, it has no way to intercept the command line arguments passed to the main method - the application has to help. Here is modified version of HelloWorld, updated to load from the command line:

```
public class HelloWorld {
    private static final StrProp NAME = StrProp.builder().build();
    
    public static void main(String[] args) {
        AndHow.findConfig().setCmdLineArgs(args); // <-- Pass cmd-line args to AndHow
        
        System.out.println("Hello, " + NAME.getValue());
    }
}
```

In the above example, we know that the only entry point is the main() method, so it is safe to configure AndHow at the top of that method.

`findConfig()` is called and all the steps outlined above take place:  If there is an `AndHowInit` instance on the classpath, it will be used to supply an `AndHowConfiguration` instance.  If not, a default instance is created.  Then, we supply the command line arguments to AndHow's configuration.  When its time to initialize (which happens when we access a value on line 7), AndHow provides the command line arguments to a `Loader` instance that knows how to parse key-value pairs from command-line.

Any attempt to call `findConfig()` after line 7 would result in a RuntimeException because AndHow has already initialized.

### Other examples of Configuring AndHow

There are two other common situations where you need to configuration AndHow:

Modifying the load order, customizing loaders, or adding new loaders is discussed in the [Changing the Load Order](https://www.andhowconfig.org/user-guide/changing-the-load-order) section.

Setting fixed values is mostly done during [testing](https://www.andhowconfig.org/user-guide/testing).
