=== Configuration

Application configuration is built on the https://github.com/lightbend/config[Typesafe Config] library. By default, Jooby supports configuration provided in Java properties, JSON, or https://github.com/lightbend/config/blob/master/HOCON.md[HOCON] format.

Jooby allows you to override any property via system properties, environment variables, or program arguments.

==== Environment

The javadoc:Environment[Environment] class manages your application's configuration and active environment names (e.g., `dev`, `prod`, `test`).

Environment names allow you to load different configuration files or toggle features (like caching or file reloading) depending on the deployment stage.

.Accessing the Environment
[source, java, role = "primary"]
----
{
  Environment env = getEnvironment();
}
----

.Kotlin
[source, kotlin, role = "secondary"]
----
{
  val env = environment
}
----

You can set active environment names in several ways:

* **Program Argument:** `java -jar myapp.jar prod,cloud` (This works when using Jooby's `runApp` methods).
* **System Property:** `java -Dapplication.env=prod -jar myapp.jar`
* **Environment Variable:** `application.env=prod`

==== Default Loading and Precedence

When you call `getEnvironment()`, Jooby searches for an `application.conf` file in the following order of priority:

1. `${user.dir}/conf/application.conf` (External file system)
2. `${user.dir}/application.conf` (External file system)
3. `classpath://application.conf` (Internal jar resource)

[NOTE]
====
`${user.dir}` refers to the directory from which the JVM was launched. Jooby **favors file system files** over classpath files, allowing you to easily externalize configuration without rebuilding your jar.
====

==== Overrides

Properties are resolved using the following precedence (highest priority first):

1. Program arguments (e.g., `java -jar app.jar foo=bar`)
2. System properties (e.g., `-Dfoo=bar`)
3. Environment variables (e.g., `foo=bar java -jar app.jar`)
4. Environment-specific property file (e.g., `application.prod.conf`)
5. Default property file (`application.conf`)

.Accessing Properties
[source, java, role="primary"]
----
{
  Environment env = getEnvironment();         // <1>
  Config conf = env.getConfig();              // <2>
  System.out.println(conf.getString("foo"));  // <3>
}
----

.Kotlin
[source, kotlin, role="secondary"]
----
{
  val env = environment                       // <1>
  val conf = env.config                       // <2>
  println(conf.getString("foo"))              // <3>
}
----

<1> Retrieve the current environment.
<2> Access the underlying `Config` object.
<3> Extract the value for the key `foo`.

==== Multi-Environment Configuration

It is best practice to keep common settings in `application.conf` and override environment-specific values in separate files named `application.[env].conf`.

.Example Structure
----
└── application.conf      (foo = "default", bar = "base")
└── application.prod.conf (foo = "production")
----

Running with `java -jar myapp.jar prod` results in:
* `foo`: `"production"` (overridden)
* `bar`: `"base"` (inherited from default)

To activate multiple environments, separate them with commas: `java -jar app.jar prod,cloud`.

==== Custom Configuration

If you want to bypass Jooby's default loading logic, you can provide custom options or instantiate the environment manually.

.Using Environment Options
[source,java,role="primary"]
----
{
  setEnvironmentOptions(new EnvironmentOptions().setFilename("myapp.conf")); // <1>
}
----

.Kotlin
[source,kotlin,role="secondary"]
----
{
  environmentOptions {
    filename = "myapp.conf" // <1>
  }
}
----

<1> Loads `myapp.conf` instead of the default `application.conf` while maintaining standard precedence rules.

.Direct Instantiation
[source,java,role="primary"]
----
{
  Config conf = ConfigFactory.load("custom.conf");           // <1>
  Environment env = new Environment(getClassLoader(), conf); // <2>
  setEnvironment(env);                                       // <3>
}
----

.Kotlin
[source,kotlin,role="secondary"]
----
{
  val conf = ConfigFactory.load("custom.conf")               // <1>
  val env = Environment(classLoader, conf)                   // <2>    
  environment = env                                          // <3>
}
----

<1> Manually load a configuration file.
<2> Wrap it in a Jooby Environment.
<3> Assign it to the application before startup.

==== Logging

Jooby uses **SLF4J**, allowing you to plug in your preferred logging framework.

===== Logback

1. **Add Dependency:** `logback-classic`.
2. **Configure:** Place `logback.xml` in your `conf` directory or classpath root.

===== Log4j2

1. **Add Dependencies:** `log4j-slf4j-impl` and `log4j-core`.
2. **Configure:** Place `log4j2.xml` in your `conf` directory or classpath root.

===== Environment-Aware Logging

Logging is also environment-aware. Jooby will look for `logback.[env].xml` or `log4j2.[env].xml` and favor them over the default files.

[IMPORTANT]
====
To ensure environment-specific logging works correctly, avoid using **static** loggers in your main App class before `runApp` is called. Static loggers force the logging framework to initialize before Jooby can apply the environment-specific configuration. Use an instance logger or Jooby's `getLog()` method instead.
====

==== Application Properties

[cols="2,1,3"]
|===
|Property | Default | Description

|`application.charset` | `UTF-8` | Charset for encoding/decoding and templates.
|`application.env` | `dev` | Active environment names. Jooby optimizes performance for non-`dev` environments.
|`application.lang` | `Locale.getDefault()` | Supported languages for `Context.locale()`.
|`application.tmpdir` | `tmp` | Temporary directory for the application. 
|`application.pid` | System assigned | The JVM process ID.
|===

See javadoc:AvailableSettings[] for a complete reference.
