Class Settings

java.lang.Object
org.apache.juneau.commons.settings.Settings

public class Settings extends Object
Encapsulates Java system properties with support for global and per-thread overrides for unit testing.

This class provides a thread-safe way to access system properties that can be overridden at both the global level and per-thread level, making it useful for unit tests that need to temporarily change system property values without affecting other tests or threads.

Settings instances are created using the Settings.Builder pattern. Use create() to create a new builder, or get() to get the singleton instance (which is created using default builder settings).

Lookup Order:

When retrieving a property value, the lookup order is:

  1. Per-thread store (if set via setLocal(String, String))
  2. Global store (if set via setGlobal(String, String))
  3. Sources in reverse order (last source added via Settings.Builder.addSource(SettingSource) is checked first)
  4. System property source (default, always second-to-last)
  5. System environment variable source (default, always last)
Sources vs Stores:
Features:
  • System property access - read Java system properties with type conversion via StringSetting
  • Global overrides - override system properties globally for all threads (stored in a SettingStore)
  • Per-thread overrides - override system properties for specific threads (stored in a per-thread SettingStore)
  • Custom sources - add arbitrary property sources (e.g., Spring properties, environment variables, config files) via the Settings.Builder
  • Disable override support - system property to prevent new global overrides from being set
  • Type-safe accessors - type conversion methods on StringSetting for common types: Integer, Long, Boolean, Double, Float, File, Path, URI, Charset
  • Resettable suppliers - settings are returned as StringSetting instances that can be reset to force recomputation
Usage Examples:

// 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(); // 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 // 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 // Create a custom Settings instance with custom sources (e.g., Spring properties) MapStore springSource = new MapStore(); springSource.set("spring.datasource.url", "jdbc:postgresql://localhost/db"); Settings custom = Settings.create() .addSource(springSource) .addSource(FunctionalSource.of(System::getProperty)) .build();

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(String, String). Existing global overrides will still be returned by get(String) until explicitly removed.

    Note: This property is read once at class initialization time when creating the singleton instance and cannot be changed at runtime. Changing the system property after the class has been loaded will have no effect on the singleton instance. However, you can create custom Settings instances using create() that ignore this property.

  • Field Details

  • Method Details

    • create

      public static Settings.Builder create()
      Creates a new builder for constructing a Settings instance.

      This method provides a convenient way to create custom Settings instances with specific configuration. The builder allows you to configure stores, sources, and other settings before building the final Settings instance.

      Example:

      // Create a custom Settings instance Settings custom = Settings.create() .globalStore(() -> new MapStore()) .localStore(() -> new MapStore()) .addSource(FunctionalSource.of(System::getProperty)) .build();

      Returns:
      A new Builder instance.
    • get

      public static Settings get()
      Returns the singleton instance of Settings.
      Returns:
      The singleton Settings instance.
    • get

      public StringSetting get(String name)
      Returns a StringSetting for the specified system property.

      The returned StringSetting is a resettable supplier that caches the lookup result. Use the StringSetting.asInteger(), StringSetting.asBoolean(), etc. methods to convert to different types.

      The lookup order is:

      1. Per-thread override (if set via setLocal(String, String))
      2. Global override (if set via setGlobal(String, String))
      3. Sources in reverse order (last source added via Settings.Builder.addSource(SettingSource) is checked first)
      4. System property source (default, always second-to-last)
      5. System environment variable source (default, always last)
      Parameters:
      name - The property name. Must not be null.
      Returns:
      A StringSetting that provides the property value, or null if not found.
    • get

      public <T> T get(String name, T def)
      Looks up a system property, returning a default value if not found.

      This method searches for a value using the same lookup order as get(String). If a value is found, it is converted to the type of the default value using toType(String, Class). Supported types include any type that has a static method with signature public static <T> T anyName(String arg) or a public constructor with signature public T(String arg), such as Boolean, Integer, Charset, File, etc.

      Example:

      // System property: -Dmy.property=true Boolean flag = get("my.property", false); // true // Environment variable: MY_PROPERTY=UTF-8 Charset charset = get("my.property", Charset.defaultCharset()); // UTF-8 // Not found, returns default String value = get("nonexistent", "default"); // "default"

      Type Parameters:
      T - The type to convert the value to.
      Parameters:
      name - The property name.
      def - The default value to return if not found.
      Returns:
      The found value (converted to type T), or the default value if not found.
      See Also:
    • setGlobal

      public Settings setGlobal(String name, String value)
      Sets a global override for the specified property.

      This override will apply to all threads and takes precedence over system properties. However, per-thread overrides (set via setLocal(String, String)) will still take precedence over global overrides.

      If the juneau.settings.disableGlobal system property is set to true, this method will throw an exception. This allows system administrators to prevent applications from overriding system properties globally.

      Setting a value to null will store an empty optional, effectively overriding the system property to return empty. Use unsetGlobal(String) to completely remove the override.

      Parameters:
      name - The property name.
      value - The override value, or null to set an empty override.
      Returns:
      This object for method chaining.
      See Also:
    • unsetGlobal

      public void unsetGlobal(String name)
      Removes a global override for the specified property.

      After calling this method, the property will fall back to the system property value (or per-thread override if one exists).

      Parameters:
      name - The property name.
      See Also:
    • setLocal

      public Settings setLocal(String name, String value)
      Sets a per-thread override for the specified property.

      This override will only apply to the current thread and takes precedence over global overrides and system properties. This is particularly useful in unit tests where you need to temporarily change a system property value without affecting other threads or tests.

      Setting a value to null will store an empty optional, effectively overriding the property to return empty for this thread. Use unsetLocal(String) to completely remove the override.

      Parameters:
      name - The property name.
      value - The override value, or null to set an empty override.
      Returns:
      This object for method chaining.
      See Also:
    • unsetLocal

      public void unsetLocal(String name)
      Removes a per-thread override for the specified property.

      After calling this method, the property will fall back to the global override (if set) or the system property value for the current thread.

      Parameters:
      name - The property name.
      See Also:
    • clearLocal

      public Settings clearLocal()
      Clears all per-thread overrides for the current thread.

      After calling this method, all properties will fall back to global overrides (if set) or system property values for the current thread.

      This is typically called in a @AfterEach or @After test method to clean up thread-local overrides after a test completes.

      Returns:
      This object for method chaining.
      See Also:
    • clearGlobal

      Clears all global overrides.

      After calling this method, all properties will fall back to resolver values (or per-thread overrides if they exist).

      Returns:
      This object for method chaining.
      See Also:
    • toType

      protected <T> T toType(String s, Class<T> c)
      Converts a string to the specified type using reflection to find conversion methods or constructors.

      This method attempts to convert a string to the specified type using the following lookup order:

      1. Custom type functions registered via Settings.Builder.addTypeFunction(Class, Function)
      2. Special handling for String (returns the string as-is)
      3. Special handling for Enum types (uses Enum.valueOf(Class, String))
      4. Reflection lookup for static methods with signature public static <T> T anyName(String arg) on the target class
      5. Reflection lookup for static methods on the superclass (for abstract classes like Charset where concrete implementations need to use the abstract class's static method)
      6. Reflection lookup for public constructors with signature public T(String arg)

      When a conversion method or constructor is found via reflection, it is cached in the toTypeFunctions map for future use.

      Examples:
      • Boolean - Uses Boolean.valueOf(String) static method
      • Integer - Uses Integer.valueOf(String) static method
      • Charset - Uses Charset.forName(String) static method (even for concrete implementations)
      • File - Uses File(String) constructor
      Type Parameters:
      T - The target type.
      Parameters:
      s - The string to convert. Must not be null.
      c - The target class. Must not be null.
      Returns:
      The converted value.
      Throws:
      RuntimeException - If the type is not supported for conversion (no static method or constructor found).