Java Application Configuration: Overview of Best Libraries and Tools
Configuration management is one of the key tasks when developing enterprise applications in Java. The flexibility, security, and maintainability of your code depend on how you organize the storage and reading of parameters (databases, API keys, ports, feature flags). In this article, we will cover three of the most popular approaches and libraries for configuring Java applications with practical examples.
1. Built-in Mechanism: java.util.Properties
The simplest way is to use the standard Properties class. It reads files in the .properties format (key=value). Suitable for small projects without complex hierarchy.
import java.io.FileInputStream;import java.io.IOException;import java.util.Properties;
public class ConfigExample { public static void main(String[] args) { Properties props = new Properties(); try (FileInputStream fis = new FileInputStream("app.properties")) { props.load(fis); String dbUrl = props.getProperty("db.url"); String dbUser = props.getProperty("db.user", "default_user"); System.out.println("URL: " + dbUrl + ", User: " + dbUser); } catch (IOException e) { e.printStackTrace(); } }}Pros: no additional dependencies required, simple syntax.
Cons: no support for nesting, types, profiles (dev/prod).
2. Typesafe Config (Lightbend Config)
The com.typesafe:config library (often used in projects with Akka, Play Framework) supports HOCON, JSON, and .properties formats. It features strict typing and the ability to merge configurations from different sources.
Example file application.conf (HOCON):
database { host = "localhost" port = 5432 credentials { user = "admin" password = ${?DB_PASSWORD} // taken from environment variable }}logging { level = "INFO"}Reading in Java:
import com.typesafe.config.Config;import com.typesafe.config.ConfigFactory;
public class TypesafeConfigExample { public static void main(String[] args) { Config config = ConfigFactory.load(); // reads application.conf String host = config.getString("database.host"); int port = config.getInt("database.port"); String user = config.getString("database.credentials.user"); String password = config.getString("database.credentials.password"); System.out.printf("Connecting to %s:%d as %s%n", host, port, user); }}Key features:
- Support for
${?VAR}for environment variable substitution. - Configuration merging: you can define a base file and override parameters for a specific environment.
- Strict type checking at read time.
- Automatic loading from classpath.
3. Spring Framework — @ConfigurationProperties
If you are using Spring Boot, configuration becomes extremely convenient. You can bind parameters from application.properties or application.yml to Java beans using annotations.
Example application.yml:
app: name: "MyApp" datasource: url: jdbc:mysql://localhost:3306/mydb username: root password: secret features: enable-cache: true max-connections: 10Java bean for mapping:
import org.springframework.boot.context.properties.ConfigurationProperties;import org.springframework.stereotype.Component;
@Component@ConfigurationProperties(prefix = "app")public class AppConfig { private String name; private Datasource datasource; private Featu