Application properties
Fluxzero provides a static utility, ApplicationProperties, for resolving configuration values across
environments, tests, and production. It supports:
- Layered resolution from environment variables, system properties, and
.propertiesfiles - Placeholder substitution (e.g.
${my.env}) - Encrypted values with automatic decryption
- Typed access:
getBooleanProperty,getIntegerProperty, etc.
Property resolution order
Section titled “Property resolution order”Properties are resolved in the following order of precedence:
EnvironmentVariablesSource– e.g.export MY_SETTING=valueSystemPropertiesSource– e.g.-Dmy.setting=valueFluxzeroAdditionalPropertiesSource– locations configured withFLUXZERO_CONFIG_LOCATIONSApplicationEnvironmentPropertiesSource– e.g.application-dev.propertiesApplicationPropertiesSource– base fallback (application.properties)FluxzeroPropertiesSource– SDK defaults (fluxzero.propertiesorfluxzero.json)- (Optional): Spring’s
Environmentis added as a fallback source if Spring is active
ApplicationPropertiesSource merges every application.properties resource visible on the application classpath.
A shared module can therefore own common defaults once; each executable that depends on that module inherits them.
Do not repeat the same key with different values across modules: the SDK logs a warning because class-loader ordering
would make that value ambiguous. Put intentional overrides in an environment variable, system property,
environment-specific file, or another higher-priority source.
Spring Boot nested JARs remain separate classpath resources and are discovered automatically. A custom uber-JAR build
that collapses equal resource names must merge overlapping application.properties files in its own packaging
configuration.
To specify the environment (dev, prod, etc.), define:
export ENVIRONMENT=devThis allows application-dev.properties to override base properties.
SDK-loaded property files accept both regular property names and their conventional environment-variable aliases. For
example, FLUXZERO_AUTH_OIDC_LOGIN_STATE_SECRET can be resolved with
ApplicationProperties.getProperty("fluxzero.auth.oidc.login-state-secret"). When both forms occur in the same source,
the exact property name takes priority.
Serialization type aliases
Section titled “Serialization type aliases”Use fluxzero.serialization.typeAliases to map legacy serialized type names to their current names during
deserialization. Separate multiple entries with commas, semicolons, or newlines. Exact aliases use source=target;
package aliases require a trailing .* on both sides:
fluxzero.serialization.typeAliases=host.example.LegacyCommand=io.example.CurrentCommand,host.example.events.*=io.example.events.*For deployment configuration, set the conventional environment variable. Quote its value so the shell leaves package wildcards unchanged:
export FLUXZERO_SERIALIZATION_TYPE_ALIASES='host.example.LegacyCommand=io.example.CurrentCommand,host.example.events.*=io.example.events.*'FLUXZERO_SERIALIZATION_TYPEALIASES is accepted as a compact alternative. Following the normal property resolution
order, the environment variable takes precedence over system properties and application*.properties. The selected
property source supplies the complete alias list; entries are not merged across property sources.
Exact aliases take precedence over package aliases, and the longest matching package prefix wins. An alias configured
through FluxzeroBuilder.addTypeAlias(...) or addPackageAlias(...) overrides a property alias with the same source.
Aliases run after revision upcasters and also apply to polymorphic @class values at any depth in JSON, JSON-encoded
message metadata read as an object, and root @class values in JSON test fixtures. See
Upcasting and downcasting for the
complete behavior.
Example usage
Section titled “Example usage”String name = ApplicationProperties.getProperty("app.name", "DefaultApp");boolean enabled = ApplicationProperties.getBooleanProperty("feature.toggle", true);int maxItems = ApplicationProperties.getIntegerProperty("limit.items", 100);val name = ApplicationProperties.getProperty("app.name", "DefaultApp")val enabled = ApplicationProperties.getBooleanProperty("feature.toggle", true)val maxItems = ApplicationProperties.getIntegerProperty("limit.items", 100)Versioned defaults
Section titled “Versioned defaults”fluxzero.defaults.version lets new applications opt into newer SDK defaults while existing applications keep
compatibility behavior when the property is absent. Use yyyy.MM.dd values. Each version includes the defaults from
earlier versions, and each behavior can still be overridden with its dedicated property.
| Defaults version | Equivalent property | What changes |
|---|---|---|
>= 2026.05.20 | fluxzero.tracking.unconfiguredHandlerConsumerMode = perHandler | Handlers without an explicit @Consumer or matching custom ConsumerConfiguration get their own generated default consumer per handler class, instead of sharing one application default consumer per message type. This isolates tracking positions and handler failures for unconfigured handlers. |
>= 2026.05.21 | fluxzero.scheduling.periodic.useDefaultInitialDelay = true | @Periodic annotations that omit initialDelay use the schedule’s natural first deadline: fixed-delay schedules first run after delay, and cron schedules first run at the next cron match. Set initialDelay = 0 to request an immediate first run. |
>= 2026.09.09 | fluxzero.websocket.reconnectBackoff.enabled = true | WebSocket reconnect attempts use equal jitter over a capped exponential delay instead of a fixed one-second interval. Set the dedicated property to false to retain fixed retries. |
>= 2026.09.10 | fluxzero.eventsourcing.maxFetchBytes = 104857600 | Aggregate-history pages request at most 100 MiB of serialized event payload. Set the dedicated property to 0 to retain count-only pages. |
For example:
fluxzero.defaults.version=2026.05.21This enables both the per-handler consumer default and the newer periodic initial-delay default. To choose one behavior
explicitly without changing the defaults version, set the dedicated property directly. Existing applications that omit
fluxzero.defaults.version keep compatibility behavior: unconfigured handlers share the application default consumer,
implicit @Periodic(initialDelay = -1) is treated as an immediate first run, WebSocket reconnects use a fixed
one-second interval, and aggregate-history pages are count-bounded only.
Encrypted values
Section titled “Encrypted values”Fluxzero supports secure storage of secrets using its built-in encryption utility. To use encryption:
-
Generate a new key with:
String key = DefaultEncryption.generateNewEncryptionKey();System.out.println(key);// => ChaCha20|KJh832h1f7shDFb... -> Save and use as ENCRYPTION_KEY -
Set the encryption key via an environment variable or system property:
Terminal window export ENCRYPTION_KEY=ChaCha20|KJh832h1f7shDFb... -
Encrypt values at build/deploy time:
String encrypted = ApplicationProperties.encryptValue("secret-google-key");System.out.println(encrypted);// => encrypted|ChaCha20|mm8yeY8TXtNpdrwO:REdej56zvFXc:b7oQdmnpQpUzagKtma9JLQ== -
Add encrypted values to your config:
google.apikey=encrypted|ChaCha20|mm8yeY8TXtNpdrwO:REdej56zvFXc:b7oQdmnpQpUzagKtma9JLQ== -
Resolve them normally in code:
String apiKey = ApplicationProperties.getProperty("google.apikey");// -> "secret-google-key"
Decryption is transparent. Fluxzero detects encrypted values and decrypts them automatically.
In tests
Section titled “In tests”Properties can be defined in your test/resources/application.properties or overridden via system properties:
-Dmy.test.override=trueOr dynamically inject mock values:
TestFixture.create(MyHandler.class) .withProperty("my.test.value", "stub") .whenCommand("/users/create-job.json") .expectSchedules(ScheduledJob.class);TestFixture.create(MyHandler::class.java) .withProperty("my.test.value", "stub") .whenCommand("/users/create-job.json") .expectSchedules(ScheduledJob::class.java)© 2026 Fluxzero