4.103.0
json-io 4.103.0
Maven Central: com.cedarsoftware:json-io:4.103.0 (requires java-util 4.103.0+)
Highlights
New features
- Streaming-write API —
JsonGenerator(Jackson-aligned cursor-style serializer). NewJsonIo.createGenerator(Writer|OutputStream)factories return aJsonGeneratorfor hand-rolled streaming output. Method set mirrors Jackson'sJsonGenerator:writeStartObject/writeEndObject/writeStartArray/writeEndArray/writeFieldName, scalar writers, rawwriteRaw/writeRawValue, convenience field writers, andcopyCurrentEvent/copyCurrentStructurebridges for parse → transform → emit pipelines. 57 new tests. JsonGenerator.writeObject(Object)— Jackson-aligned databind entry point driving the same code path asJsonIo.toJson(cycle tracking,@id/@ref, custom-writer dispatch,@typepolicy). Identity-map sharing acrosswriteObjectcalls preserves graph identity across multiple top-level emits undercycleSupport(true). PluswriteObjectField(String, Object)andwriteBinary(byte[])(wrapped form by default; bare base64 undershowTypeInfoNever(), round-tripping via java-util 4.103.0'sMapConversions.toByteArray).JsonIo.formatJsonreimplemented as a parse-and-re-emit pipeline throughJsonTokenizer+JsonGenerator— output now byte-identical totoJson(prettyPrint=true); the 214-LOCJsonPrettyPrinteris deleted. NewformatJson(String, WriteOptions)overload; throwsJsonIoExceptionon parse failure.JsonClassWritergains a Jackson-aligned,JsonGenerator-based emission API — retires custom writers' direct dependence onjava.io.Writer(theWriter-taking forms are@Deprecatedfor removal in 5.0). All 19 built-in writers migrated;Writer-based forms retained as bridge delegates.- Directional Jackson-aligned ignore controls —
@IoProperty(access = WRITE_ONLY|READ_ONLY),@IoIgnoreProperties(allowGetters/allowSetters), plus directional field-exclusion aliases onReadOptionsBuilder/WriteOptionsBuilder. - New TOON
ReadOptions—toonExpandPaths(boolean)(spec §13.4 dotted-key path expansion) andtoonIndentSize(int), each with permanent siblings.
Performance
JsonIo.createTokenizer(...)caches the defaultReadOptionsinstead of building a fresh one per null-options call, and borrowsFastReaderbuffers from the thread-local recycler. java-json-benchmark stream-deser ofUsersJSON vs Jackson: 1KB 34.5x → 1.96x, 10KB 7.09x → 1.46x (faster than Gson).- Primitive-field reads in
Accessorno longer autobox — aVarHandlebound into anXGetterlambda per primitive type (gated by JDK ≥ 9; JDK 8 source-compat preserved).Integer/Doublewrappers fromAccessor.retrieveeliminated,Longreduced ~80%. CharStreamTokenizernumber parsing writes directly into typed instance fields and no longer eagerly stringifies tokens (lazygetText()). Median-of-3: Maps Read -5.7%, POJO Read -16.3%.- Typed primitive-array inline-write loops in
ToonWriter(~3-7% ratio improvement); SIMD char-array cache-verify via java-util'sVectorizedArrays.equalsRange;writeImplnarrow snap+restore (~2-3% Write improvement).
Refactor
- JsonWriter dog-food migration complete — structural emission (
{/}/[/]/separators/indents/@id/@type/@ref/@items/@keys) now fully driven throughCharStreamGenerator's state machine; the parallelcontextStackmachine is eliminated. Net ~-200 LOC. Behavior changes:writeStringField's legacy "always emit leading comma" removed (gen auto-decides, matching Jackson); pretty-printname: valuespacing normalized to Jackson convention. - Extracted
JsonTokenizer(Jackson-style cursor API) andCharStreamTokenizerfromJsonParser(shrinks ~1,590 → ~590 lines).
Correctness
- TOON read/write brought into full conformance with the toonformat.dev v3.3 spec — the complete upstream fixture suite passes.
CharStreamTokenizerstrict mode rejects trailing-decimal numbers (1.,1.e2) per RFC 8259;getIntValue/getLongValueenforce Jackson overflow contracts; wrong-token-type getters throw instead of returning stale state.
Full changelog: https://github.com/jdereg/json-io/blob/master/changelog.md