Skip to content

Quick Start

Petrus Pradella edited this page Jun 27, 2026 · 6 revisions

Quick Start

This walks from an empty file to a typed, documented, reloadable config.

1. Open a config over a file

import br.com.finalcraft.finalconfig.config.Config;
import br.com.finalcraft.finalconfig.codec.jackson.YamlCodec;
import java.nio.file.Paths;

Config cfg = Config.open(Paths.get("server.yml"), new YamlCodec());

Config.open never throws on a bad file: an absent file starts empty, and a malformed one is backed up to .bak and starts empty (see Lifecycle, Reload & Watching).

2. Read and write by path

cfg.setValue("server.host", "localhost");   // auto-vivifies the "server" object
cfg.setValue("server.port", 25565);

String host = cfg.getString("server.host");
int port    = cfg.getInt("server.port", 25565);   // 2nd arg is the default if absent

3. Seed defaults that document themselves

getOrSetDefaultValue writes the default (and a comment) only if the path is absent, so it is safe to call on every startup:

int maxPlayers = cfg.getOrSetDefaultValue("server.max-players", 20, "hard player cap");
boolean pvp    = cfg.getOrSetDefaultValue("server.pvp", true, "allow player-vs-player");

4. Save

cfg.save();   // atomic write; comments and key order preserved

The resulting server.yml:

server:
  host: localhost
  port: 25565
  # hard player cap
  max-players: 20
  # allow player-vs-player
  pvp: true

5. Bind to a typed object (optional)

class ServerConfig {
    public String host = "localhost";
    public int port = 25565;

    @Key(transformCase = KeyTransformCase.KEBAB_CASE)
    public int maxPlayers = 20;     // <-> key "max-players"

    @PostInject
    void validate() {
        if (port < 1 || port > 65535) throw new IllegalStateException("bad port");
    }
}

ServerConfig sc = cfg.loadAs(ServerConfig.class, new YamlCodec());   // bind + run @PostInject
sc.maxPlayers = 50;
cfg.mergeFrom(sc, new YamlCodec());   // merge back into the tree (unknown keys survive)
cfg.save();

6. Switch format — change one line

Everything above stays identical; only the codec (and extension) change:

Config cfg = Config.open(Paths.get("server.toml"), new TomlCodec());
// or new JsonCodec() / new JsoncCodec()

→ Next: Architecture Overview · The Dynamic API

Clone this wiki locally