Skip to main content

JSONL

Juneau supports converting arbitrary POJOs to and from JSONL (JSON Lines, also called NDJSON) using native serializers and parsers. JSONL is a text format where each line is a valid JSON value, separated by newlines. It is the standard format for LLM fine-tuning datasets, streaming AI inference, log aggregation, and bulk data pipelines.

The JsonlSerializer converts POJOs directly to JSONL format, and the JsonlParser creates POJOs directly from JSONL by parsing each line as a JSON value.

JSONL support is included in juneau-marshall.

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

Quick Start​

// A simple bean
public class Person {
public String name;
public int age;
public Person() {}
public Person(String name, int age) { this.name = name; this.age = age; }
}

// Serialize a list of beans to JSONL
List<Person> people = List.of(new Person("Alice", 30), new Person("Bob", 25));
String jsonl = Jsonl.of(people);

Produces:

{"name":"Alice","age":30}
{"name":"Bob","age":25}

Parsing​

// Parse JSONL into a list of beans
List<Person> parsed = Jsonl.to(jsonl, List.class, Person.class);

// Parse into an array
Person[] array = Jsonl.to(jsonl, Person[].class);

// Parse a single line
Person p = Jsonl.to("{\"name\":\"Alice\",\"age\":30}", Person.class);

// Parse into a list of maps
List<JsonMap> maps = Jsonl.to(jsonl, List.class, JsonMap.class);

Serialization​

// Use the default serializer
String jsonl = JsonlSerializer.DEFAULT.write(someObject);

// Use the marshaller for convenience
String jsonl = Jsonl.of(someObject);

Bean-to-JSONL Mapping​

The conversion follows the JSONL specification:

  • Collections and arrays → One JSON value per line (no wrapping brackets)
  • Single bean or map → One JSON line
  • Strings → JSON string literals, one per line
  • Numbers → JSON number literals, one per line
  • Booleans → true / false, one per line
  • Null → null, one per line
  • Nested objects → Stay compact on a single line per outer element
  • ObjectSwaps → Applied for non-JSON-primitive types (e.g. byte arrays, dates)

Media Types​

  • Produces: application/jsonl
  • Accepts: application/jsonl, application/jsonlines (the JSON Lines spec's suggested type; alias), application/x-ndjson, text/jsonl

REST Integration​

// JSONL support is included via BasicUniversalConfig (there is no dedicated JSONL-only config interface).
@Rest
public class MyResource extends RestServlet implements BasicUniversalConfig { ... }

Limitations​

  • No pretty-printing: Each JSON value must fit on a single line; useWhitespace() is always suppressed.
  • First-line-only for single-object targets: When parsing JSONL to a single non-collection type, only the first non-empty line is parsed; trailing lines are ignored.
  • No multi-line JSON input: Each JSON value must be on a single line; pretty-printed JSON will cause parse errors.

Annotations​

@JsonlConfig applies to both JsonlSerializer and JsonlParser on a REST class or method (see Context Annotations). Its only attribute today is rank; JSONL has no @Jsonl data annotation or @JsonlApply, so bean-level behavior comes from the @Json family and the shared bean annotations.

@Rest
@JsonlConfig
public class MyResource extends BasicRestServlet { ... }
See Also
  • JSON Lines Specification for the full format definition.
  • JSON5L Basics — the relaxed-dialect sibling that tolerates comments, unquoted keys, and single quotes per line.
  • Marshallers for the marshaller API overview.
  • Token-Streaming Basics — JSONL is a FULL streaming format because each line is itself a JSON value that maps cleanly onto the token cursor.