Overview
ConfIO is a lightweight and easy-to-use Java library for INI-style configuration files. It supports hierarchical and ordered sections (key-value, text, JSON), a general section for global parameters, comment handling, type-safe accessors and iterator-based navigation. The parser can auto-detect section types or use the __type__ meta-parameter.
Universal INI Parser
Line-by-line parsing with support for multiple section types and ordered sections.
General / Global Parameters
Parameters before the first section are available via a general section object.
Multiple Section Types
KEY_VALUE, TEXT and JSON sections; explicit or automatic detection.
Hot-reload & Overrides
Environment/profile overrides and optional watcher with change notifications.
Quick Start
Load a configuration file and read global parameters and sections:
import java.nio.file.Path;
import com.siperf.confio.*;
import com.siperf.confio.sections.*;
// Load configuration from file
ConfigurationFile config = ConfigurationFileLoader.load(Path.of("config.ini"));
// Get global parameters (general section)
String serverNumber = config.getGlobalParameter("server.number");
// Get a named section
if (config.hasSection("database")) {
KeyValueSection db = config.getSection("database", KeyValueSection.class);
String driver = db.getParameter("driver.classname");
boolean enabled = Boolean.parseBoolean(db.getParameter("enabled"));
}
API Highlights
ConfigurationFileLoader
Static utilities to load configuration from Path, InputStream, String or Reader with charset options.
ConfigurationFile
Primary interface to query sections, general section, raw lines and to iterate over sections.
Section
Represents a section (KEY_VALUE / TEXT / JSON) and provides typed accessors, raw content and content lines.
Examples
Sample configuration (config.ini)
; Global parameters
app.name = ConfIO demo
app.version = 0.3.0
server.number = 1
; Database section with nested subsections and typed hints
[database]
driver.classname = org.postgresql.Driver
url = jdbc:postgresql://db.example.com:5432/appdb
enabled = true
[database.credentials]
username = admin
password = secret
[database.pool]
pool.size = 5
pool.max = 50
; A text section (preserve full text, e.g. dialplan)
[asterisk.dialplan]
__type__= text
exten => s,1,Answer()
exten => s,n,Playback(hello-world)
exten => s,n,Dial(SIP/1001,20)
; JSON section (explicit type)
[routing.rules]
__type__ = json
{
"default": { "timeout": 30, "retries": 3 },
"priority": [{ "route": "fast", "weight": 10 }]
}
1) Loading configuration (file and embedded)
//Loading external configuration
Path configPath = Paths.get("config.ini");
ConfigurationFile externalConfig = ConfigurationFileLoader.load(configPath);
// Loading internal configuration
ConfigurationFile embeddedConfig = ConfigurationFileLoader.loadFromEmbeddedResource(ConfIOTest.class, "embedded.ini");
2) Global parameters
// Loading configuration
ConfigurationFile config = ConfigurationFileLoader.load("config.ini");
// Get global parameters
String serverNumber = config.getGlobalParameter("server.number", "0");
String appName = config.getGlobalParameter("app.name", "Unknown");
String appVersion = config.getGlobalParameter("app.version");
// Check if parameter exists
boolean hasServerNumber = config.hasGlobalParameter("server.number");
// Get all global parameters
Map globalParams = config.getGlobalParameters();
3) Key‑Value sections
// Loading configuration
ConfigurationFile config = ConfigurationFileLoader.load("config.ini");
// Loading DB section
var dbSection = config.getSection("database", KeyValueSection.class);
Objects.requireNonNull(dbSection);
String driver = dbSection.getParameter("driver.classname");
String url = dbSection.getParameter("url");
String enabled = dbSection.getParameter("enabled", "false");
4) Text sections
// Loading configuration
ConfigurationFile config = ConfigurationFileLoader.load("config.ini");
// Loading dialplan section
var dialplanSection = config.getSection("asterisk.dialplan", TextSection.class);
Objects.requireNonNull(dialplanSection);
// Loading section content
String content = dialplanSection.getContent();
List lines = dialplanSection.getContentLines();
5) JSON sections
// Loading configuration
ConfigurationFile config = ConfigurationFileLoader.load("config.ini");
// Loading routing rules section
JsonSection rulesSection = config.getSection("routing.rules", JsonSection.class);
Objects.requireNonNull(rulesSection);
// Get JSON content
String jsonContent = rulesSection.getContent();
// Get as lines
List jsonLines = rulesSection.getContentLines();
6) Subsections
// Loading configuration
ConfigurationFile config = ConfigurationFileLoader.load("config.ini");
// Loading DB section
var dbSection = config.getSection("database", KeyValueSection.class);
Objects.requireNonNull(dbSection);
// Loading credentials subsection
var credentialsSection = dbSection.getSubsection("credentials", KeyValueAbstractSection.class);
Objects.requireNonNull(credentialsSection);
String password = credentialsSection.getParameter("password");
String user = credentialsSection.getParameter("username");
// Loading pool subsection
var dbPoolSection = dbSection.getSubsection("pool", KeyValueAbstractSection.class);
Objects.requireNonNull(dbPoolSection);
//Using a validation integer accessor
int size = Integer.parseInt(dbPoolSection.getParameter("pool.size"));
int max = Integer.parseInt(dbPoolSection.getParameter("pool.max"));
7)Validation assessors
// Loading configuration and required sections
ConfigurationFile config = ConfigurationFileLoader.load("config.ini");
var dbSection = config.getSection("database", KeyValueSection.class);
var credentialsSection = dbSection.getSubsection("credentials", KeyValueAbstractSection.class);
var dbPoolSection = dbSection.getSubsection("pool", KeyValueAbstractSection.class);
//Obtaining a simple text
String password = credentialsSection.getParameter("password");
//Using a validation accessor configured with a parameter chain to obtain a string parameter.
String user = credentialsSection.string()
.notBlank()
.notEmpty()
.withAllowedValues("admin", "user", "guest")
.getOrDefault("username", "guest");
//Using a validation integer accessor to obtain int parameters
int size = dbPoolSection.integer().getOrDefault("pool.size", 1);
int max = dbPoolSection.integer().getOrDefault("pool.max", 100);
8) List all sections
// Loading configuration
ConfigurationFile config = ConfigurationFileLoader.load("config.ini");
// Get all section names
List sectionNames = config.getSectionNames();
// Check if section exists
boolean hasDatabaseSection = config.hasSection("database");
boolean hasNonExistentSection = config.hasSection("non.existent");
Installation
Add ConfIO to your Maven project:
<dependency>
<groupId>com.siperf</groupId>
<artifactId>confio</artifactId>
<version>0.3.0</version>
</dependency>
Changelog
0.3.0 — 2026-01-13
- Support for nested sections and hierarchical configuration.
- Extended typed accessors and iterator support for sections.
- BREAKING: Replaced globalParameters with generalSection API.
0.2.0 — 2025-05-17
- Initial release: universal INI-style parser, key-value/text/JSON sections and comment handling.