Flattened bundle. Content from source markdown guides is inlined below.
A quick introduction to loading configuration with avaje-config.
Add the dependency to your pom.xml:
<dependency>
<groupId>io.avaje</groupId>
<artifactId>avaje-config</artifactId>
<version>2.5</version>
</dependency>Create a application.yaml file in src/main/resources:
server:
port: 8080
ssl:
enabled: false
database:
host: localhost
port: 5432
name: myappAccess configuration in your code:
import io.avaje.config.Config;
public class MyApplication {
public static void main(String[] args) {
int serverPort = Config.getInt("server.port");
String dbHost = Config.get("database.host");
boolean sslEnabled = Config.getBool("server.ssl.enabled", false);
}
}Avaje Config supports multiple configuration sources (in priority order):
- System properties:
-Dserver.port=9000 - Environment variables:
SERVER_PORT=9000 - Application properties file:
application.yaml - Default values in code
For larger applications, use type-safe configuration classes:
@Config
public class AppConfig {
public final String dbHost;
public final int dbPort;
public AppConfig(String dbHost, int dbPort) {
this.dbHost = dbHost;
this.dbPort = dbPort;
}
}Use in your code:
public class MyService {
private final AppConfig config;
public MyService(AppConfig config) {
this.config = config;
}
}- Learn about default values
- Load profile-specific configuration
- Use environment variables
This guide provides step-by-step instructions for integrating avaje-config into a Java project using Maven. It covers basic setup and common usage patterns for retrieving configuration properties.
avaje-config is a lightweight configuration library that loads and manages application properties from YAML and properties files. It provides:
- Automatic loading of configuration from standard locations
- Type-safe property access (String, int, long, boolean)
- Simple, fluent API for retrieving values
Add avaje-config to your pom.xml:
<dependency>
<groupId>io.avaje</groupId>
<artifactId>avaje-config</artifactId>
<version>5.1</version>
</dependency>Replace 5.1 with the latest version from Maven Central.
Create src/main/resources/application.yaml for production configuration with reasonable defaults:
# Application configuration
app:
name: MyApplication
version: 1.0.0
port: 8080
timeout-seconds: 30
debug: false
# Database configuration
database:
url: jdbc:postgresql://localhost:5432/myapp
username: appuser
max-pool-size: 10
# Feature flags
features:
logging-enabled: trueAlternative with properties format - src/main/resources/application.properties:
app.name=MyApplication
app.version=1.0.0
app.port=8080
app.timeout-seconds=30
app.debug=false
database.url=jdbc:postgresql://localhost:5432/myapp
database.username=appuser
database.max-pool-size=10
features.logging-enabled=trueCreate src/test/resources/application-test.yaml for test-specific configuration:
# Override settings for testing
app:
port: 8081
debug: true
database:
url: jdbc:h2:mem:test
username: sa
max-pool-size: 2
features:
logging-enabled: falseAlternative with properties format - src/test/resources/application-test.properties:
app.port=8081
app.debug=true
database.url=jdbc:h2:mem:test
database.username=sa
database.max-pool-size=2
features.logging-enabled=falseimport io.avaje.config.Config;
public class AppConfig {
public static String getAppName() {
// Get value, throws exception if not found
return Config.get("app.name");
}
public static String getAppName(String defaultName) {
// Get value with default if not found
return Config.get("app.name", defaultName);
}
public static String getDatabaseUrl() {
return Config.get("database.url", "jdbc:h2:mem:default");
}
}public class AppConfig {
public static int getPort() {
// Get integer value
return Config.getInt("app.port");
}
public static int getPort(int defaultPort) {
// Get integer with default
return Config.getInt("app.port", defaultPort);
}
public static int getMaxPoolSize() {
return Config.getInt("database.max-pool-size", 5);
}
}public class AppConfig {
public static long getTimeoutMillis() {
// Get long value
return Config.getLong("app.timeout-millis", 30000L);
}
}public class AppConfig {
public static boolean isDebugEnabled() {
// Get boolean value
return Config.getBool("app.debug");
}
public static boolean isLoggingEnabled() {
return Config.getBool("features.logging-enabled", true);
}
}As an alternative to using static Config methods, you can obtain the underlying Configuration object and use it directly. This approach is useful when you want to pass configuration as a parameter, store it as an instance variable, or access it from multiple methods.
import io.avaje.config.Config;
import io.avaje.config.Configuration;
Configuration configuration = Config.asConfiguration();The Configuration object provides the same methods as the static Config class:
public class AppService {
private final Configuration configuration;
public AppService() {
this.configuration = Config.asConfiguration();
}
public void initialize() {
// Get string values
String appName = configuration.get("app.name");
String appName = configuration.get("app.name", "DefaultApp");
// Get integer values
int port = configuration.getInt("app.port");
int port = configuration.getInt("app.port", 8080);
// Get long values
long timeout = configuration.getLong("app.timeout-millis", 30000L);
// Get boolean values
boolean debug = configuration.getBool("app.debug");
boolean debug = configuration.getBool("app.debug", false);
}
}public class DatabaseService {
private final Configuration config;
public DatabaseService() {
this.config = Config.asConfiguration();
}
public void setupConnection() {
String url = config.get("database.url");
String user = config.get("database.username");
int poolSize = config.getInt("database.max-pool-size", 10);
System.out.println("Connecting to: " + url);
System.out.println("User: " + user);
System.out.println("Pool size: " + poolSize);
}
}| Scenario | Approach |
|---|---|
| Quick property access in a method | Use static Config methods |
| Storing configuration as instance variable | Use Configuration object |
| Passing configuration to methods/constructors | Use Configuration object |
| Dependency injection scenarios | Use Configuration object |
| One-off property lookups | Use static Config methods |
Both approaches access the same underlying configuration, so choose based on your code structure and preferences.
public class MyApplication {
public static void main(String[] args) {
String appName = Config.get("app.name", "MyApp");
int port = Config.getInt("app.port", 8080);
boolean debug = Config.getBool("app.debug", false);
System.out.println("Starting " + appName + " on port " + port);
if (debug) {
System.out.println("Debug mode enabled");
}
}
}public class DatabaseService {
private final String dbUrl;
private final String dbUser;
private final int maxPoolSize;
public DatabaseService() {
this.dbUrl = Config.get("database.url");
this.dbUser = Config.get("database.username");
this.maxPoolSize = Config.getInt("database.max-pool-size", 10);
}
public void connect() {
System.out.println("Connecting to " + dbUrl);
// Initialize connection pool with maxPoolSize
}
}When your application starts, avaje-config automatically loads properties in this order:
- Main resources -
src/main/resources/application.yamlor.properties - Test resources (when running tests) -
src/test/resources/application-test.yamlor.properties - Later sources override earlier ones - Test configuration takes precedence over main configuration
This means:
- Define default values in
application.yaml(main resources) - Override specific values in
application-test.yamlwhen running tests - Your tests run with test-specific configuration automatically
Create a configuration class to centralize all property access:
public class Config {
public static String appName() {
return io.avaje.config.Config.get("app.name", "MyApplication");
}
public static int port() {
return io.avaje.config.Config.getInt("app.port", 8080);
}
public static String databaseUrl() {
return io.avaje.config.Config.get("database.url");
}
public static int maxPoolSize() {
return io.avaje.config.Config.getInt("database.max-pool-size", 10);
}
}
// Usage:
int port = Config.port();
String dbUrl = Config.databaseUrl();Use configuration to initialize services:
public class DatabaseConnectionPool {
private final String url;
private final int maxSize;
public DatabaseConnectionPool() {
this.url = io.avaje.config.Config.get("database.url");
this.maxSize = io.avaje.config.Config.getInt("database.max-pool-size", 10);
}
public void initialize() {
// Set up connection pool
}
}When running tests, avaje-config automatically uses application-test.yaml or application-test.properties:
@Test
public void testWithTestConfiguration() {
// This test automatically uses application-test.yaml
// Port will be 8081 (from test config)
int port = Config.getInt("app.port");
assertEquals(8081, port);
}src/
├── main/
│ └── resources/
│ ├── application.yaml # Main configuration (production defaults)
│ └── application.properties # Alternative format for main config
└── test/
└── resources/
├── application-test.yaml # Test configuration overrides
└── application-test.properties # Alternative format for test config
- Review the avaje-config documentation for advanced features
- Consider creating a wrapper class for type-safe configuration access
- Use environment-specific values to handle different deployment environments
- Organize your configuration hierarchically (use dot notation like
app.port,database.url)
Property not found exception:
- Ensure the property exists in
application.yamlorapplication-test.yaml - Check property naming - use consistent dot notation (e.g.,
app.portnotapp-port) - Verify the file is in the correct location (
src/main/resourcesorsrc/test/resources)
Test uses wrong configuration:
- Ensure
application-test.yamlorapplication-test.propertiesexists insrc/test/resources - Verify filename spelling exactly matches
Values not updated:
- Stop and restart your application
- Configuration is loaded once at startup
How to provide sensible defaults for configuration properties.
Provide a default when reading a property:
import io.avaje.config.Config;
// Returns 8080 if not configured
int port = Config.getInt("server.port", 8080);
// Returns "localhost" if not configured
String host = Config.get("server.host", "localhost");
// Returns false if not configured
boolean ssl = Config.getBool("server.ssl.enabled", false);Use constructor parameters with defaults:
@Config
public class AppConfig {
public final int serverPort;
public final String serverHost;
public final boolean sslEnabled;
public AppConfig(
@ConfigProperty(value = "server.port", defValue = "8080") int serverPort,
@ConfigProperty(value = "server.host", defValue = "localhost") String serverHost,
@ConfigProperty(value = "server.ssl.enabled", defValue = "false") boolean sslEnabled
) {
this.serverPort = serverPort;
this.serverHost = serverHost;
this.sslEnabled = sslEnabled;
}
}Specify defaults in application.yaml:
server:
port: 8080
host: localhost
ssl:
enabled: false
keystore: classpath:keystore.jks
database:
connections: 10
timeout: 30| Approach | Use When |
|---|---|
| Direct call defaults | Simple, single properties |
| Configuration class defaults | Multiple related properties, type safety |
| YAML file defaults | Defaults shared across environments |
Defaults can be overridden by:
- System properties:
java -Dserver.port=9000 - Environment variables:
export SERVER_PORT=9000 - Configuration files for current environment:
application-prod.yaml
See Profiles for loading environment-specific defaults.
- Learn about environment-specific profiles
- Use environment variables