Skip to main content

TOML

Juneau supports converting arbitrary POJOs to and from TOML (Tom's Obvious Minimal Language) using native serializers and parsers implemented without any external dependencies. TOML is a configuration file format that maps unambiguously to hash tables, widely used in projects like Cargo (Rust) and Python's pyproject.toml. The TomlSerializer converts POJOs directly to TOML format, and the TomlParser creates POJOs directly from TOML without intermediate DOM objects.

TOML support is included in juneau-marshall.

Maven
<dependency>
<groupId>org.apache.juneau</groupId>
<artifactId>juneau-marshall</artifactId>
<version>${juneau.version}</version>
</dependency>

Quick Start​

// Serialize a map to TOML
Map<String, Object> config = new LinkedHashMap<>();
config.put("name", "myapp");
config.put("port", 8080);

Map<String, Object> db = new LinkedHashMap<>();
db.put("host", "localhost");
db.put("port", 5432);
config.put("database", db);

String toml = Toml.of(config);

Produces:

name = "myapp"

[database]
host = "localhost"
port = 5432

Parsing​

// Parse TOML into a Map or JsonMap
JsonMap parsed = Toml.to(toml, JsonMap.class);
String name = parsed.getString("name");
JsonMap dbConfig = parsed.getMap("database");
String host = (String) dbConfig.get("host");
Long port = (Long) dbConfig.get("port");

// Parse into a bean
MyConfig config = Toml.to(toml, MyConfig.class);

Serialization​

// Use the default serializer
String toml = TomlSerializer.DEFAULT.write(someObject);

// Use the marshaller for convenience
String toml = Toml.of(someObject);

Supported TOML Features​

The implementation conforms to the TOML v1.0.0 specification:

  • Key-value pairs - Strings, integers, floats, booleans, dates, and arrays
  • Tables - [section] and nested [parent.child] tables
  • Inline tables - {key = "value"} for simple nested structures
  • Arrays - Homogeneous arrays of primitives, strings, and inline tables
  • Strings - Basic ("..."), literal ('...'), and multi-line variants
  • Dates and times - LocalDate, LocalTime, LocalDateTime, OffsetDateTime (ISO 8601)

Bean-to-TOML Mapping​

  • Simple properties become key-value pairs.
  • Nested beans and string-keyed maps become [table] sections (or inline tables, see below).
  • Collections of simple values become arrays (tags = ["a", "b"]).
  • Collections of beans/maps become arrays of tables ([[name]]).
  • Null properties are omitted (TOML has no null); see nullValue below.
  • Maps with non-string keys have their keys converted with toString().
  • Root-level arrays use [[item]] for beans/maps, or a _value wrapper for primitives and simple arrays.

Pre-configured instances​

InstanceDescription
TomlSerializer.DEFAULTDefault settings.
TomlSerializer.DEFAULT_READABLESame, with ws() (whitespace) enabled.
TomlParser.DEFAULTDefault parser.

Serializer settings​

Configured through TomlSerializer.create() (see TomlSerializer.Builder), in addition to the settings inherited from WriterSerializer.

Builder methodDefaultDescription
useInlineTables(boolean)trueWrite small nested objects as inline tables (addr = {city = "Boston", state = "MA"}) instead of [table] sections.
inlineTableThreshold(int)3Maximum number of properties for a nested object to be written inline.
sortKeys(boolean)falseSort keys alphabetically in the output.
nullValue(String)"<NULL>"String written for null values when keepNullProperties() is enabled. Chosen so it is not confused with the literal string "null".
useWhitespace() / ws()offInherited whitespace setting.
TomlSerializer s = TomlSerializer.create()
.useInlineTables(false)
.sortKeys(true)
.build();

With useInlineTables(false), a bean having a nested address bean is written as:

age = 30
name = "Alice"
tags = ["a", "b"]

[address]
city = "Boston"
state = "MA"

Null handling:

// Write null properties as nick = "~" rather than omitting them.
TomlSerializer s = TomlSerializer.create().keepNullProperties().nullValue("~").build();

Parser settings​

Builder methodDefaultDescription
nullValue(String)"<NULL>"A string value equal to this marker is parsed as Java null. Must match the serializer's nullValue.
// Round-trip nulls using a custom marker.
TomlParser p = TomlParser.create().nullValue("~").build();
MyBean b = p.read(toml, MyBean.class);

Notes:

  • TOML has no native duration type; quoted ISO 8601 duration strings (e.g. "PT1H30M") parse to Duration.
  • A bare 4-digit integer parses as a Long rather than a Year; use a quoted string for Year.

Media Types​

  • Produces: application/toml
  • Accept: application/toml, text/toml

REST Integration​

// Use BasicTomlConfig for TOML-only REST resources
@Rest
public class MyResource extends RestServlet implements BasicTomlConfig { ... }

// TOML is also included in BasicUniversalConfig
@Rest
public class MyResource extends RestServlet implements BasicUniversalConfig { ... }

Annotations​

@TomlConfig applies to both TomlSerializer and TomlParser on a REST class or method (see Context Annotations). Its only attribute today is rank; TOML has no @Toml data annotation or @TomlApply.

See Also