Skip to content

4.103.0

Choose a tag to compare

@jdereg jdereg released this 06 Jun 15:16
· 23 commits to master since this release

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). New JsonIo.createGenerator(Writer|OutputStream) factories return a JsonGenerator for hand-rolled streaming output. Method set mirrors Jackson's JsonGenerator: writeStartObject/writeEndObject/writeStartArray/writeEndArray/writeFieldName, scalar writers, raw writeRaw/writeRawValue, convenience field writers, and copyCurrentEvent/copyCurrentStructure bridges for parse → transform → emit pipelines. 57 new tests.
  • JsonGenerator.writeObject(Object) — Jackson-aligned databind entry point driving the same code path as JsonIo.toJson (cycle tracking, @id/@ref, custom-writer dispatch, @type policy). Identity-map sharing across writeObject calls preserves graph identity across multiple top-level emits under cycleSupport(true). Plus writeObjectField(String, Object) and writeBinary(byte[]) (wrapped form by default; bare base64 under showTypeInfoNever(), round-tripping via java-util 4.103.0's MapConversions.toByteArray).
  • JsonIo.formatJson reimplemented as a parse-and-re-emit pipeline through JsonTokenizer + JsonGenerator — output now byte-identical to toJson(prettyPrint=true); the 214-LOC JsonPrettyPrinter is deleted. New formatJson(String, WriteOptions) overload; throws JsonIoException on parse failure.
  • JsonClassWriter gains a Jackson-aligned, JsonGenerator-based emission API — retires custom writers' direct dependence on java.io.Writer (the Writer-taking forms are @Deprecated for 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 on ReadOptionsBuilder/WriteOptionsBuilder.
  • New TOON ReadOptionstoonExpandPaths(boolean) (spec §13.4 dotted-key path expansion) and toonIndentSize(int), each with permanent siblings.

Performance

  • JsonIo.createTokenizer(...) caches the default ReadOptions instead of building a fresh one per null-options call, and borrows FastReader buffers from the thread-local recycler. java-json-benchmark stream-deser of Users JSON vs Jackson: 1KB 34.5x → 1.96x, 10KB 7.09x → 1.46x (faster than Gson).
  • Primitive-field reads in Accessor no longer autobox — a VarHandle bound into an XGetter lambda per primitive type (gated by JDK ≥ 9; JDK 8 source-compat preserved). Integer/Double wrappers from Accessor.retrieve eliminated, Long reduced ~80%.
  • CharStreamTokenizer number parsing writes directly into typed instance fields and no longer eagerly stringifies tokens (lazy getText()). 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's VectorizedArrays.equalsRange; writeImpl narrow snap+restore (~2-3% Write improvement).

Refactor

  • JsonWriter dog-food migration complete — structural emission ({/}/[/]/separators/indents/@id/@type/@ref/@items/@keys) now fully driven through CharStreamGenerator's state machine; the parallel contextStack machine is eliminated. Net ~-200 LOC. Behavior changes: writeStringField's legacy "always emit leading comma" removed (gen auto-decides, matching Jackson); pretty-print name: value spacing normalized to Jackson convention.
  • Extracted JsonTokenizer (Jackson-style cursor API) and CharStreamTokenizer from JsonParser (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.
  • CharStreamTokenizer strict mode rejects trailing-decimal numbers (1., 1.e2) per RFC 8259; getIntValue/getLongValue enforce 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