Settings Package
The org.apache.juneau.commons.settings package provides a thread-safe way to access system properties with support for global and per-thread overrides, making it useful for unit tests and configuration management.
Key Classes
Settings
Encapsulates Java system properties with support for global and per-thread overrides.
// Get a system property as a StringSetting (using singleton instance)
StringSetting setting = Settings.get().get("my.property");
String value = setting.get(); // Get the string value
// Get with type conversion using StringSetting methods
Setting<Integer> intSetting = Settings.get().get("my.int.property").asInteger();
Setting<Long> longSetting = Settings.get().get("my.long.property").asLong();
Setting<Boolean> boolSetting = Settings.get().get("my.bool.property").asBoolean();
Setting<Double> doubleSetting = Settings.get().get("my.double.property").asDouble();
Setting<Float> floatSetting = Settings.get().get("my.float.property").asFloat();
Setting<File> fileSetting = Settings.get().get("my.file.property").asFile();
Setting<Path> pathSetting = Settings.get().get("my.path.property").asPath();
Setting<URI> uriSetting = Settings.get().get("my.uri.property").asURI();
Setting<Charset> charsetSetting = Settings.get().get("my.charset.property").asCharset();
// Use custom type conversion
Setting<MyCustomType> customSetting = Settings.get().get("my.custom.property")
.asType(MyCustomType.class);
// Reset a setting to force recomputation
setting.reset();
Per-Thread Overrides
// Override for current thread (useful in unit tests)
Settings.get().setLocal("my.property", "test-value");
// ... test code that uses the override ...
Settings.get().unsetLocal("my.property"); // Remove specific override
// OR
Settings.get().clearLocal(); // Clear all thread-local overrides
Global Overrides
// Set global override (applies to all threads)
Settings.get().setGlobal("my.property", "global-value");
// ... code that uses the global override ...
Settings.get().unsetGlobal("my.property"); // Remove specific override
// OR
Settings.get().clearGlobal(); // Clear all global overrides
Custom Settings Instance
// Create a custom Settings instance with custom sources
<java-class><a href="/site/apidocs/org/apache/juneau/commons/settings/MapStore.html" target="_blank">MapStore</a></java-class> springSource = new MapStore();
springSource.set("spring.datasource.url", "jdbc:postgresql://localhost/db");
Settings custom = Settings.create()
.addSource(springSource)
.addSource(<java-class><a href="/site/apidocs/org/apache/juneau/commons/settings/FunctionalSource.html" target="_blank">FunctionalSource</a></java-class>.of(System::getProperty))
.build();
Lookup Order
When retrieving a property value, the lookup order is:
- Per-thread store (if set via
setLocal()) - Global store (if set via
setGlobal()) - Sources in reverse order (last source added is checked first)
- System property source (default, always second-to-last)
- System environment variable source (default, always last)
Setting Sources and Stores
SettingSource
Provides read-only access to property values.
// Functional source
SettingSource source = <java-class><a href="/site/apidocs/org/apache/juneau/commons/settings/FunctionalSource.html" target="_blank">FunctionalSource</a></java-class>.of(System::getProperty);
// Map-based source
<java-class><a href="/site/apidocs/org/apache/juneau/commons/settings/MapStore.html" target="_blank">MapStore</a></java-class> store = new MapStore();
store.set("key", "value");
SettingSource source2 = store; // Stores extend SettingSource
SettingStore
Provides read/write access to property values.
// Map store
<java-class><a href="/site/apidocs/org/apache/juneau/commons/settings/MapStore.html" target="_blank">MapStore</a></java-class> store = new MapStore();
store.set("key", "value");
String value = store.get("key");
// Functional store
<java-class><a href="/site/apidocs/org/apache/juneau/commons/settings/FunctionalStore.html" target="_blank">FunctionalStore</a></java-class> store2 = FunctionalStore.of(
key -> getValue(key), // Getter
(key, value) -> setValue(key, value) // Setter
);
StringSetting
A specialized Setting for string values that provides convenience methods for type conversion.
StringSetting setting = Settings.get().get("my.property");
// Type conversions
Setting<Integer> intValue = setting.asInteger();
Setting<Long> longValue = setting.asLong();
Setting<Boolean> boolValue = setting.asBoolean();
Setting<Double> doubleValue = setting.asDouble();
Setting<Float> floatValue = setting.asFloat();
Setting<File> fileValue = setting.asFile();
Setting<Path> pathValue = setting.asPath();
Setting<URI> uriValue = setting.asURI();
Setting<Charset> charsetValue = setting.asCharset();
// Custom type conversion
Setting<MyType> customValue = setting.asType(MyType.class);
// Reset to force recomputation
setting.reset();
Common Patterns
Unit Testing with Thread-Local Overrides
@Test
void testWithOverride() {
// Override system property for this test
Settings.get().setLocal("my.property", "test-value");
try {
// Test code that uses the property
String value = Settings.get().get("my.property").get();
assertEquals("test-value", value);
} finally {
// Clean up
Settings.get().clearLocal();
}
}
Configuration with Custom Sources
// Create settings with multiple sources
MapStore configFile = new MapStore();
// Load from config file
configFile.set("app.name", "MyApp");
configFile.set("app.version", "1.0.0");
Settings settings = Settings.create()
.addSource(configFile) // Check config file first
.addSource(FunctionalSource.of(System::getProperty)) // Then system properties
.build();
String appName = settings.get("app.name").get();
System Properties
juneau.settings.disableGlobal(system property) orJUNEAU_SETTINGS_DISABLEGLOBAL(system env) - If set totrue, prevents new global overrides from being set viasetGlobal(). Existing global overrides will still be returned until explicitly removed.
Share feedback or follow-up questions for this page directly through GitHub.