Skip to main content

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:

  1. Per-thread store (if set via setLocal())
  2. Global store (if set via setGlobal())
  3. Sources in reverse order (last source added is checked first)
  4. System property source (default, always second-to-last)
  5. 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) or JUNEAU_SETTINGS_DISABLEGLOBAL (system env) - If set to true, prevents new global overrides from being set via setGlobal(). Existing global overrides will still be returned until explicitly removed.

See Also

Discussion

Share feedback or follow-up questions for this page directly through GitHub.