-
Notifications
You must be signed in to change notification settings - Fork 16
Getting Started
This guide will help you set up Okaeri Configs in your project and create your first configuration.
- Java 8 or higher
- Maven or Gradle build system
Okaeri Configs supports multiple configuration formats. Choose the one that best fits your needs:
| Format | Module | Best For |
|---|---|---|
| YAML | okaeri-configs-yaml-snakeyaml |
General purpose, widely recognized |
| XML/INI |
okaeri-configs-xml or okaeri-configs-properties
|
Standalone apps, zero external dependencies |
| JSON | okaeri-configs-json-gson |
In-app storage, GSON users |
| YAML (Bukkit) | okaeri-configs-yaml-bukkit |
Minecraft Bukkit/Spigot/Paper plugins |
| YAML (Bungee) | okaeri-configs-yaml-bungee |
Minecraft BungeeCord/Waterfall plugins |
📋 More formats available: TOML, HJSON, and additional JSON/YAML backends. See Home for full comparison.
- Add the repository:
<repositories>
<repository>
<id>okaeri-releases</id>
<url>https://repo.okaeri.cloud/releases</url>
</repository>
</repositories>- Add the dependency (example with YAML SnakeYAML):
<dependencies>
<dependency>
<groupId>eu.okaeri</groupId>
<artifactId>okaeri-configs-yaml-snakeyaml</artifactId>
<version>{VERSION}</version>
</dependency>
</dependencies>- Add the repository:
repositories {
maven("https://repo.okaeri.cloud/releases")
}- Add the dependency (example with YAML SnakeYAML):
dependencies {
implementation("eu.okaeri:okaeri-configs-yaml-snakeyaml:{VERSION}")
}- Add the repository:
repositories {
maven { url "https://repo.okaeri.cloud/releases" }
}- Add the dependency (example with YAML SnakeYAML):
dependencies {
implementation 'eu.okaeri:okaeri-configs-yaml-snakeyaml:{VERSION}'
}Create a class that extends OkaeriConfig:
import eu.okaeri.configs.OkaeriConfig;
import eu.okaeri.configs.annotation.Comment;
import eu.okaeri.configs.annotation.Header;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@Header("My Application Configuration")
public class MyConfig extends OkaeriConfig {
@Comment("The name of your application")
private String applicationName = "MyApp";
@Comment("Maximum number of concurrent users")
private int maxUsers = 100;
@Comment("Enable debug mode")
private boolean debug = false;
}💡 Tip: Using Lombok with
@Getterand@Setterannotations can reduce boilerplate significantly! All examples in this wiki use Lombok. See Using Lombok for installation and setup guide.
import eu.okaeri.configs.ConfigManager;
import eu.okaeri.configs.yaml.snakeyaml.YamlSnakeYamlConfigurer;
import java.io.File;
public class Main {
public static void main(String[] args) {
MyConfig config = ConfigManager.create(MyConfig.class, (it) -> {
it.configure(opt -> {
opt.configurer(new YamlSnakeYamlConfigurer()); // Set format
opt.bindFile(new File("config.yml")); // Set file location
});
it.saveDefaults(); // Create file if it doesn't exist
it.load(true); // Load and update with comments
});
// Use the config
System.out.println("App Name: " + config.getApplicationName());
System.out.println("Max Users: " + config.getMaxUsers());
// Modify and save
config.setMaxUsers(200);
config.save();
}
}MyConfig config = (MyConfig) ConfigManager.create(MyConfig.class)
.configure(opt -> {
opt.configurer(new YamlSnakeYamlConfigurer());
opt.bindFile(new File("config.yml"));
})
.saveDefaults()
.load(true);
// Use the config
String appName = config.getApplicationName();After running your code, you'll find a config.yml file with this content:
# My Application Configuration
# The name of your application
applicationName: MyApp
# Maximum number of concurrent users
maxUsers: 100
# Enable debug mode
debug: falseUnderstanding the config lifecycle is important:
-
Create:
ConfigManager.create()instantiates your config class -
Configure:
configure(opt -> { ... })sets format, file, and other options -
Save Defaults:
saveDefaults()creates the file with default values if it doesn't exist -
Load:
load()reads the file and populates your config object -
Update:
load(true)also saves after loading to update comments and new fields
// Creates file with defaults if missing, then loads it
MyConfig config = ConfigManager.create(MyConfig.class, (it) -> {
it.configure(opt -> {
opt.configurer(new YamlSnakeYamlConfigurer());
opt.bindFile("config.yml");
});
it.saveDefaults();
it.load(); // load only, don't save after
});// Creates file, loads it, and updates with any new fields/comments
MyConfig config = ConfigManager.create(MyConfig.class, (it) -> {
it.configure(opt -> {
opt.configurer(new YamlSnakeYamlConfigurer());
opt.bindFile("config.yml");
});
it.saveDefaults();
it.load(true); // load and save to update comments/new fields
});// Removes keys from file that don't exist in your config class
MyConfig config = ConfigManager.create(MyConfig.class, (it) -> {
it.configure(opt -> {
opt.configurer(new YamlSnakeYamlConfigurer());
opt.bindFile("config.yml");
opt.removeOrphans(true); // remove undeclared keys
});
it.saveDefaults();
it.load(true); // load and save to update comments/new fields
});Depending on your chosen format, use the appropriate configurer:
// YAML
new YamlSnakeYamlConfigurer() // General purpose
new YamlJacksonConfigurer() // Via Jackson
new YamlBukkitConfigurer() // Bukkit/Spigot/Paper
new YamlBungeeConfigurer() // BungeeCord/Waterfall
// TOML
new TomlJacksonConfigurer() // TOML 1.0 via Jackson
// JSON
new JsonGsonConfigurer() // Via Google GSON
new JsonJacksonConfigurer() // Via Jackson
new JsonSimpleConfigurer() // Via json-simple
// HJSON
new HjsonConfigurer() // Human-friendly JSON
// XML
new XmlSimpleConfigurer() // Human-readable XML
// Properties/INI (zero dependencies)
new PropertiesConfigurer() // key=value format
new IniConfigurer() // [section] formatYou can use java.nio.file.Path instead of File:
import java.nio.file.Path;
import java.nio.file.Paths;
Path configPath = Paths.get("config.yml");
MyConfig config = ConfigManager.create(MyConfig.class, (it) -> {
it.configure(opt -> {
opt.configurer(new YamlSnakeYamlConfigurer());
opt.bindFile(configPath);
});
it.saveDefaults();
it.load(true); // load and save to update comments/new fields
});Or even use a string pathname directly:
MyConfig config = ConfigManager.create(MyConfig.class, (it) -> {
it.configure(opt -> {
opt.configurer(new YamlSnakeYamlConfigurer());
opt.bindFile("configs/myapp.yml"); // string pathname
});
it.saveDefaults();
it.load(true); // load and save to update comments/new fields
});// This will fail!
public class MyConfig extends OkaeriConfig {
public MyConfig(String name) { // Custom constructor
// ...
}
}Solution: Always provide a no-args constructor (or don't define any constructors):
public class MyConfig extends OkaeriConfig {
// No constructor = default constructor is implicit
}private int port; // Will default to 0, can't be nullSolution: Use wrapper classes when null is a valid value:
private Integer port; // Can be nullMyConfig config = ConfigManager.create(MyConfig.class, (it) -> {
it.configure(opt -> {
opt.configurer(new YamlSnakeYamlConfigurer());
opt.bindFile("config.yml");
});
// Forgot to load!
});
// Config has only default values, file contents are ignoredSolution: Always call load() or load(true):
it.load(); // load only, don't save after
it.load(true); // load and save to update comments/new fieldsprivate transient String apiKey; // Will NOT be saved/loaded!Solution: Only use transient for fields you don't want in the config file (runtime data only).
Now that you have a basic config working, explore these topics:
- Configuration Basics - Learn about all supported types and features
- Annotations Guide - Master @Comment, @Header, @Variable, and more
- Subconfigs & Serialization - Organize complex configurations
- Collections & Maps - Work with lists, sets, and maps
- Validation - Add validation to your configs
- Examples & Recipes - See more complete examples
Having issues? Check the Troubleshooting guide or ask for help on our Discord.