Skip to content

fix(deps): bump: bump com.cedarsoftware:json-io from 4.105.0 to 4.108.0#431

Open
dependabot[bot] wants to merge 1 commit into
mainfrom
dependabot/gradle/main/com.cedarsoftware-json-io-4.108.0
Open

fix(deps): bump: bump com.cedarsoftware:json-io from 4.105.0 to 4.108.0#431
dependabot[bot] wants to merge 1 commit into
mainfrom
dependabot/gradle/main/com.cedarsoftware-json-io-4.108.0

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Jul 9, 2026

Copy link
Copy Markdown
Contributor

Bumps com.cedarsoftware:json-io from 4.105.0 to 4.108.0.

Release notes

Sourced from com.cedarsoftware:json-io's releases.

4.107.0

json-io 4.107.0

Releases in lock-step with java-util 4.107.0. The theme is multi-threaded read performance.

Concurrent-read scaling (via java-util 4.107.0). json-io now runs on java-util 4.107.0, which removes the dominant lock on the concurrent deserialization path — ClassUtilities.trySetAccessible's synchronizedMap(WeakHashMap), probed on every object instantiation and field injection. Under 13-thread load ~74% of worker threads were BLOCKED on that single monitor; after the fix, zero. This is the headline win for services deserializing JSON concurrently.

Performance — getClassFactory caching (+2–3% read throughput). For every ordinary POJO (no explicit factory), factory resolution re-ran a fallback chain on every object read, including a reflective Class.isRecord() Method.invoke — ~3% of CPU under concurrent reads. The result is stable per class, so it's now memoized in a ConcurrentHashMap, eliminating the per-object reflection. Measured +2–3% throughput across 1/4/8/12 threads, with the reflective frames gone from the profile.

Performance — getCustomReader allocation fix. The custom-reader lookup no longer allocates a capturing lambda on every call; a get()-first fast path removes one per-object allocation on the hot read path.

Build — Spring Boot 3.x/4.x verification. Both Spring modules (json-io-spring-boot-starter, json-io-spring-ai-toon) now carry a -Pspring-boot4 profile, giving repeatable checks against Boot floor 3.4, ceiling 3.5.x, and 4.1 / Spring 7 — one artifact runs on both Boot majors.

Also: a string-heavy databind read regression guard and a multi-threaded read/profiling mode were added to JsonPerformanceTest (the harness used to find and verify the above).


Full changelog: https://github.com/jdereg/json-io/blob/master/changelog.md

4.106.0

json-io 4.106.0

Maven Central: com.cedarsoftware:json-io:4.106.0

Highlights

Spring Boot 3.x and 4.x — one artifact, and your app owns Spring

  • The json-io-spring-boot-starter now declares Spring as provided and compiles against a Spring Boot 3.4 (Spring 6.2) floor via the spring-boot-dependencies BOM. It forces no Spring version onto your build — your Boot version always wins, and a consumer of the starter inherits only json-io (→ java-util) on its compile classpath.
  • The shipped auto-config was reworked to use only Spring Framework-level APIs (WebMvcConfigurer / WebFluxConfigurer / ServerCodecConfigurer, and by-name @AutoConfiguration(afterName=…) ordering), so it carries no Boot-version-specific type and runs on both Spring Boot 3.x and 4.x from a single artifact — runtime-verified against Spring Boot 4.1 / Spring 7 (mvn test -Pspring-boot4).
  • json-io's core remains standalone (its only runtime dependency is java-util); the starter is an optional, non-intrusive add-on.

Correctness

  • BufferRecycler re-entrancy fix: the per-thread recycler behind JsonIo.createTokenizer (and the other recycler-backed read/write paths) freed the pooled buffer's in-use flag unconditionally on close(), so a nested tokenizer/parser created during a suspended outer parse could free — then a later borrow could clobber — the outer's still-in-use buffer (EOF reached while reading JSON string, Object not ended with '}', etc.). Release is now ownership-aware (identity-checked): a holder only frees the buffer it actually borrowed. New regression test.

Jackson interoperability

  • json-io now honors Jackson 3.x databind annotations. @JsonNaming/@JsonDeserialize moved from com.fasterxml.jackson.databind.annotation (2.x) to tools.jackson.databind.annotation (3.x); both packages are detected, so a POJO annotated with either Jackson major is respected. The com.fasterxml.jackson.annotation.* family was already major-agnostic. Detection remains reflection-only — no compile-time Jackson dependency.
  • JsonTokenizer gains Jackson-parity lenient number accessors getValueAsInt() / getValueAsLong() / getValueAsDouble() (non-number tokens coerced via java-util's Converter) and isClosed() (mirrors Jackson's JsonParser.isClosed()).

Build / Security

  • Runtime dependency java-util 4.105.0 → 4.106.0 (lock-free ClassUtilities.forName name-cache fast path, ClassUtilities.newInstance fixes, security hardening).
  • Test-scope jackson-databind pinned to 2.21.4 to avoid CVE-2026-54515 (a @JsonIgnoreProperties deserialization-bypass regression introduced in 2.22.0, with no fixed 2.22.x release yet) — test scope only, never shipped.
  • Plugin bumps: central-publishing-maven-plugin 0.11.0, jacoco-maven-plugin 0.8.15.

JDK compatibility: core is JDK 8+; the Spring modules require Java 17.

Full details in changelog.md.

Changelog

Sourced from com.cedarsoftware:json-io's changelog.

4.108.0 - 2026-07-09

  • BUG FIX: CharStreamTokenizer string slow-path (taken once a JSON string reaches 256 plain characters — the size of the inline readBuf — before its first escape) passed the \ backslash delimiter to readStringWithEscapes instead of the character after it. So \" decoded to a literal \ and the escaped quote then terminated the string one character early, corrupting the value and, inside an object, throwing Object not ended with '}'. The borrowed-buffer path, the small-buffer path, and the escape inner-loop all already read the char after the backslash first; only this slow path did not. Fix: after detecting the \ delimiter, read the following escape character and hand that to readStringWithEscapes (in.read() transparently crosses a FastReader buffer refill). Found in the wild by n-cube's Update from HEAD, where a large /cmd payload carried a merged-PR note containing quotes and JsonIo.toJava failed to parse the request. New regression tests JsonTokenizerTest.escapeAfterLongPlainRun{DecodesCorrectly,ParsesToMap} sweep pad lengths {256, 300, 1000, 8190, 8200} at both the tokenizer and JsonIo.toJavaMap levels (red before / green after).
  • TESTING: TOON buffer-boundary coverage — ToonReaderTest.toonLongStringWithEscapesAtBufferBoundariesRoundTrips and toonQuotedKeyWithEscapesAcrossBoundaryRoundTrips round-trip escaped long string values and quoted keys whose escapes land at/around the 256 (readBuf), 4096 (ToonReader line buffer), and 8192 (FastReader) boundaries, guarding the TOON reader's escape handling against the same class of slow-path/refill error.
  • BUILD: Runtime dependency java-util 4.107.0 → 4.108.0 (lock-step; adds FastReader buffer-boundary regression tests — no behavioral change).

4.107.0 - 2026-07-06

  • BUILD: json-io-spring-ai-toon gains a -Pspring-boot4 profile matching the starter's, so both Spring modules now have repeatable Spring Boot 3.x/4.x verification (mvn test = floor 3.4, -Pspring-ceiling = 3.5.x, -Pspring-boot4 = 4.1 / Spring 7). The AI module needed no code rework — its auto-config uses only stable Boot APIs (@AutoConfiguration, @ConditionalOn*, @ConfigurationProperties; no web auto-config) and its tests use ApplicationContextRunner (no Boot test slices), so its full suite runs against Boot 4 with no exclusions.
  • PERFORMANCE: ReadOptionsBuilder.DefaultReadOptions.getClassFactory(Class) now caches its full result per class. For any class with no explicit factory (i.e. every ordinary POJO) it previously re-ran a fallback chain on every object readThrowable/enum/record checks, where the record test is a reflective Class.isRecord() Method.invoke. JFR showed this at ~3% of CPU during concurrent reads (getClassFactory/isRecord/Method.invoke samples). The outcome is stable per class (config is frozen after build()), so it is now memoized in a plain ConcurrentHashMap (get()-first, NO_FACTORY sentinel), eliminating the per-object reflection. Measured on the multi-threaded databind read: +2–3% throughput across 1/4/8/12 threads (all thread counts improved; the reflective frames disappear from the profile), and single-threaded read is a hair faster with no behavior change.
  • PERFORMANCE: ReadOptionsBuilder.DefaultReadOptions.getCustomReader(Class) no longer allocates a capturing lambda on every call. It used computeIfAbsent, whose lambda argument is allocated on every invocation (hit or miss); after warmup every class is cached (with a nullReader sentinel), so a get()-first fast path now allocates nothing on the hot read path — one fewer per-object allocation during deserialization. (Allocation-profiler-driven; removes the per-object allocation flagged in java-json-benchmark's json-io read profile.)

4.106.0 - 2026-07-05

  • BUILD: Runtime dependency java-util 4.105.0 → 4.106.0 (brings the lock-free ClassUtilities.forName name-cache fast path — a direct win for json-io's @type resolution under concurrency — plus ClassUtilities.newInstance array-default/conversion-direction fixes and security hardening).
  • BUILD: Plugin bumps — central-publishing-maven-plugin 0.10.0 → 0.11.0, jacoco-maven-plugin 0.8.14 → 0.8.15. All other available updates were deliberately held to preserve JDK 8 compatibility (junit-jupiter 6.x, mockito 5.x, assertj-core 4.x require Java 11/17) or because they are breaking majors needing a planned migration (spring-boot 4.x / Spring Framework 7.x / spring-ai 2.x / reactor 3.8.x, which also pull in Jackson 3). Test-scope jackson-databind pinned 2.22.0 → 2.21.4 to avoid CVE-2026-54515 (a case-insensitive @JsonIgnoreProperties deserialization-bypass regression introduced in 2.22.0, with no fixed 2.22.x release yet; 2.21.4 predates it) — test scope only, never shipped; gson 2.14.0 is the latest 2.x.
  • BUILD: The Spring modules (json-io-spring-boot-starter, json-io-spring-ai-toon) now declare Spring/Spring-AI as provided and resolve versions from an imported spring-boot-dependencies BOM pinned to a floor (Spring Boot 3.4 / Spring 6.2, via ${spring-boot.bom}). json-io is compiled once against the floor and forces no Spring version onto consumers — the host application supplies Spring at its own version; a consumer of the starter inherits only json-io (→ java-util) on its compile classpath. Floor-compiled bytecode links forward across the Boot 3.x line to a ceiling of the latest Spring Boot 3.5.x (still Spring 6.2, ${spring-boot.ceiling}); mvn test -Pspring-ceiling runs the full suite at that ceiling. The starter's shipped auto-config was reworked to use only Spring Framework-level APIs (WebMvcConfigurer/WebFluxConfigurer/ServerCodecConfigurer, and by-name @AutoConfiguration(afterName=…) ordering) so it carries no Boot-version-specific type and runs on both Spring Boot 3.x and 4.x from a single artifact; mvn test -Pspring-boot4 runtime-verifies the auto-config beans, HTTP message converters, and reactive codecs against Spring Boot 4.1 / Spring 7. (The @AutoConfigureMockMvc/TestRestTemplate integration tests continue to run on Boot 3.x — those Boot test slices moved packages in Boot 4 with no string-based fallback.) To make this work cleanly, the shared test-lib version management (junit/mockito/assertj/gson/jackson/jtokkit) moved from the parent pom into the json-io core module (the only module that uses them), so the Spring modules' Boot BOM manages their own aligned junit/mockito/jackson test stack without a parent pin fighting it.
  • BUG FIX: The per-thread BufferRecycler behind JsonIo.createTokenizer (and the other recycler-backed read/write paths) is now re-entrancy safe. Its close hook released the pooled reader/pushback (and writer/byte) buffers by clearing an in-use flag unconditionally, so a nested tokenizer/parser created while an outer parse was suspended — one that had correctly received a fresh fallback buffer because the pool was already in use — freed the outer holder's flag on close(). A subsequent borrow then handed out the outer's still-in-use buffer and clobbered it mid-parse (EOF reached while reading JSON string, Object not ended with '}', etc.). Release is now ownership-aware: a holder only frees the pooled buffer it actually borrowed (identity check). Surfaced by testing nested streaming parses. New regression test JsonTokenizerTest.nestedTokenizersDoNotCorruptSuspendedOuter.
  • ENHANCEMENT: JsonTokenizer gains the Jackson-parity lenient number accessors getValueAsInt(), getValueAsLong(), and getValueAsDouble(). A number token uses the fast strict getter; any other token (e.g. a numeric string "123") is coerced through java-util's Converter, matching Jackson's getValueAsXxx() semantics (including "12.7"12 truncation). The strict getIntValue()/getLongValue()/getDoubleValue() getters are unchanged and still require a number token.
  • ENHANCEMENT: JsonTokenizer.isClosed() added for parity with Jackson's JsonParser.isClosed() — returns true once close() has been called (reaching end-of-input alone does not close the tokenizer; nextToken() returns null at EOF). Lets the common while (!tokenizer.isClosed()) drain idiom port directly from Jackson.
  • ENHANCEMENT: json-io now honors Jackson 3.x databind annotations. @JsonNaming and @JsonDeserialize moved from com.fasterxml.jackson.databind.annotation (Jackson 2.x) to tools.jackson.databind.annotation (Jackson 3.x); AnnotationResolver now detects both packages, so a POJO annotated with either major's @JsonNaming(PropertyNamingStrategies.*) or @JsonDeserialize(as=...) is respected. The com.fasterxml.jackson.annotation.* annotations (@JsonProperty, @JsonCreator, @JsonTypeInfo, etc.) were already major-agnostic — Jackson 3.x reuses the 2.x jackson-annotations jar — so they needed no change. Detection remains reflection-only (no compile-time Jackson dependency); with neither jar present the paths short-circuit at zero cost.
  • TESTING: TestUtil (the shared round-trip harness) no longer instantiates Gson and Jackson on every serialize/deserialize call — it now cross-checks only json-io's own JSON/TOON/JSON5 round-trips of the same object (their three-way agreement is the real correctness signal). Removes ~110 lines and a per-call new ObjectMapper() + new Gson() allocation across the whole suite; the Jackson databind engine is now exercised in exactly one place, JsonPerformanceTest. The gson and jackson-databind test dependencies remain — still used by JsonPerformanceTest and the @Json* annotation-interop tests.
Commits

Dependabot compatibility score

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


Dependabot commands and options

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot show <dependency name> ignore conditions will show all of the ignore conditions of the specified dependency
  • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)

Bumps [com.cedarsoftware:json-io](https://github.com/jdereg/json-io) from 4.105.0 to 4.108.0.
- [Release notes](https://github.com/jdereg/json-io/releases)
- [Changelog](https://github.com/jdereg/json-io/blob/master/changelog.md)
- [Commits](https://github.com/jdereg/json-io/commits)

---
updated-dependencies:
- dependency-name: com.cedarsoftware:json-io
  dependency-version: 4.108.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot dependabot Bot added dependencies Pull requests that update a dependency file java Pull requests that update java code labels Jul 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file java Pull requests that update java code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants