A sleek, usable, and fully-featured configuration library. Supports HOCON, TOML, and YAML.
Documentation is in the /docs/ folder.
Version 2 is still in the preview stage while we stabilize the API; for version 1.0, see the "master" branch.
- Extensible and user-friendly. All types use the same framework, and library users can easily add new types.
- Type safety. Configuration is an immutable interface.
- Automatically update old configurations with the latest keys. No need to version config files.
- No NULLs. No public mutable fields. No stringly-typed spaghetti such as
getString("key"), and no type-unsafe calls likegetInt("maybe-not-really-an-integer"). - Informative, helpful error reports. Messages that human beings (even non-programmers!) can understand. Reports key path and line number, and library error messages can even be translated depending on the locale.
DazzleConf is a clean, well-tested library to meet your configuration needs. It's quick to get running, and all you need to do is provide an interface:
Configuration<AppConfig> configuration = Configuration.defaultBuilder(AppConfig.class).build();
Backend backend = new YamlBackend(new PathRoot(Path.of("config.yml")));
AppConfig config = configuration.configureOrFallback(backend, new StandardErrorPrint(output -> output.printTo(System.out)));
// DONE! You now have a user-friendly, type-safe configuration system
if (config.woah()) {
System.out.println(config.awesome());
}
interface AppConfig {
default boolean woah() { return true; }
@Comments("An awesome comment")
default String awesome() { return "hello world"; }
@IntegerRange(min = 1, max = 100)
default long boundedNumeric() { return 10; }
@SubSection MoreStuff moreStuff();
interface MoreStuff {
@Comments(value = "Inline comment", location = CommentLocation.INLINE)
default String userMessage() { return "Hello user"; }
@Comments("Every annotation shown above works here too")
default String flexibility() {
return "Also, methods are inherited if this interface extends another, enabling inheritable config interfaces";
}
}
}When using the YAML backend, the following result is generated by writing the default configuration.
Notice how keys are mapped to lower-snake-case. This happens automatically depending on the backend you choose.
woah: true
# An awesome comment
awesome: hello world
more-stuff:
user-message: 'Hello user' # Inline comment
# Every annotation shown above works here too
flexibility: 'Also, methods are inherited if this interface extends another, enabling inheritable config interfaces'The same document can be reparsed to an instance of the configuration interface. Type and constraint validation is performed when the configuration is loaded, not when the methods are called - having an instance of the config interface is enough to ensure the configuration is valid.
We offer multiple configuration formats depending on your preference. Simply depend on the artifact matching the format you want.
| Format | Reference | Artifact | Comment Support |
|---|---|---|---|
| HOCON | HOCON.md | dazzleconf-hocon |
Writing only |
| TOML | TOML 1.0 spec | dazzleconf-toml |
Writing only |
| YAML | YAML 1.2 spec | dazzleconf-yaml |
Full |
Check out this page to get started using the library: Getting started. The documentation has many examples such as with setting up a reloadable configuration, automatically updating the configuration with the latest keys, and more.
- Serializers can depend on each other.
- Full generics support. Support for infinitely nested generics, collections, configuration subsections, etc.
List<List<List<List<MyType>>>>is fully usable, requiring no extra code.- Library users can write their own type like
MyGeneric<T>, extract the generic parameter T, and get a serializer for T. - Anything you can imagine is possible. Even generic parameters on the configuration itself are supported. For example,
MyConfig<V>with a methodV myOption(). - Annotations are usable as well.
- Immutable and thread safe by design.
- Values loaded once and never modified thereafter.
- Loading is fail-fast: if a configured value from the text file is not interpretable as the desired return type, it is rejected.
- Reading and writing:
- Read from file. ✔️
- Write to file. ✔️
- Combined read/write operation, to update existing data. ✔️
- Can write any object implementing the configuration interface (not just implementations by the library).
- Reloading:
- Easy-to-reload "shell" instance can be created, to swap the values in a live configuration.
- Migrations:
- Detect old versions, and migrate safely to latest version.
- Lets you change keys, move keys around, and merge or separate sections.
- Lets you migrate from other configuration libraries when their files exist on disk.
- Notifications. Caller can listen for:
- When data is updated with a better representation. E.g.
"3" -> 3orfAlSE->false. - When missing keys are added.
- If using migrations, when migrations are triggered.
- When data is updated with a better representation. E.g.
- Excellent and translatable error messages:
- Select user locale, or auto-detect default locale.
- Community can provide translations of all messages.
- If you made a mistake as a developer, error message includes information needed to fix the problem.
- Backends:
- HOCON, TOML, and YAML implemented so far.
- No external dependencies: they are shaded in.
- Relevant library features (key format, comment support) automatically adapt to the backend in use.
- Low-level
DataTreeAPI:- Can read and write data, independent of the backend.
- Can read and write comments if the backend supports it, including document-level header and footer.
- Comments can be placed above, below, or inline.
Not yet implemented:
- Streaming API for more efficient read/write.
- Would make I/O more efficient.
- Could skip intermediate structures like unnecessary maps and lists, and have them created in an on-demand basis.
- Greater communication between backend format and configuration definition, where the configuration interface gives the backend hints about which basic types (e.g., string or integer) and type structures (scalar/map/array) are preferred
- Planned to be combined with the streaming API.
- Java 8
Java 11 is recommended, but not required.
module-info files are also included, and these are backwards compatible with Java 8.
See the docs folder of this repository for documentation on using this library.
Additionally, the javadocs are published with the artifact. They can also be browsed here.
LGPL. See the license file for more information.