Skip to content

4.98.0

Choose a tag to compare

@jdereg jdereg released this 08 Mar 23:07
· 354 commits to master since this release

Highlights

  • @IoShowType annotation — new field-level annotation (26th) that forces @type/$type emission on polymorphic fields regardless of showTypeInfo mode. Jackson's @JsonTypeInfo on a field is honored as a fallback synonym.
  • JSON5 defaults alignment.json5() now sets showTypeInfoNever() and cycleSupport(false), matching TOON conventions where type information is controlled via annotations.
  • ToonWriter bug fixes — type metadata indentation, char[] serialization, and complex map key StackOverflow resolved.
  • Significant performance optimizations across ToonReader, ToonWriter, JsonWriter, and JsonObject hot paths.
  • JSON5 added as 5th serialization test path — all existing round-trip tests now automatically cover JSON5 format.

Features

  • @IoShowType — field-level annotation that forces @type/$type emission on the annotated field's value and its elements (Collections, Maps, arrays), regardless of showTypeInfoNever(), JSON5, or TOON mode. Essential for polymorphic fields. Jackson's @JsonTypeInfo on a field acts as a fallback synonym.
  • .json5() on WriteOptionsBuilder now sets showTypeInfoNever() and cycleSupport(false) as defaults, aligning JSON5 with TOON conventions. Individual settings can still be overridden after calling .json5().
  • Spring auto-configuration — now provides a separate toonWriteOptions bean with cycleSupport(false) for TOON/JSON5 formats, in addition to the primary jsonIoWriteOptions bean.

Bug Fixes

  • ToonWriter — nested collections and arrays with type metadata (showTypeInfoAlways()) now emit properly indented $type/$items blocks. Previously, the compact fieldName[N]: path bypassed writeCollection()/writeArray() entirely.
  • ToonWriterchar[] fields now serialize as a plain string value instead of comma-separated characters, matching the Converter's String → char[] read path.
  • ToonWriter — maps with complex keys (e.g., HashMap as key) no longer cause StackOverflowError. Routes to writeMap() with @keys/@values format instead of writeMapInline().
  • EnumSetFactory — infers enum element type from field generic declaration (EnumSet<Color>Color.class). Empty EnumSets now round-trip correctly when field provides generic type information.

Improvements

  • Field-context type resolution — enums, integer map keys, and EnumSets work consistently across JSON and TOON via generic type inference from seedIncrementalContainerMetadata().
  • JsonObject — internal storage mode consolidated from two boolean flags into a single byte with four named states; cached effectiveValues eliminates repeated conditional dispatch.
  • TOON same-type round-trip — Converter-supported types written as bare strings without $type; read back uses String → OriginalType converter path.

Performance

  • JsonIo.toToon() — defaults to cycleSupport(false), skipping traceReferences() pre-pass for ~35-40% faster TOON serialization.
  • ToonReader.cacheSubstring() — probes cache by source range before materializing substring, eliminating allocation on cache hits.
  • ToonReader — lazy trimmed line materialization, buffer-direct scalar parsing, and combined field[N]... header parsing from existing slices.
  • ToonReader — TOON string/input-stream reads reuse FastReader character buffer via scoped buffer recycler.
  • ToonWriter — tabular POJO detection validates uniformity via WriteFieldPlan accessors; row values streamed from accessors, eliminating N intermediate map allocations.
  • JsonWriter — tracking structures allocated lazily based on cycleSupport mode, avoiding ~6 KB wasted allocations when disabled.
  • JsonWriter.writeCollectionElement() — fast-paths Integer, Float, Short, Byte directly to writePrimitive().
  • JsonWriter.writeCollection() — indexed list.get(i) for RandomAccess lists instead of Iterator allocation.
  • JsonObject — deferred keys[]/values[] allocation using shared empty sentinel; appendFieldForParser() avoids redundant null assignments.

Testing

  • Added TOON as 4th and JSON5 as 5th serialization path in TestUtil, enabling all existing round-trip tests to automatically cover both formats. JSON5: 1 write fail (same custom writer edge case as json-io), 0 read fails.

Install

Maven

<dependency>
  <groupId>com.cedarsoftware</groupId>
  <artifactId>json-io</artifactId>
  <version>4.98.0</version>
</dependency>

Gradle

implementation 'com.cedarsoftware:json-io:4.98.0'