spring-projects / spring-projects/spring-boot
Kotlin Serialization does not back off when JSON-B is the only JSON converter
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 81.5k
- Forks
- 42.7k
- Avg merge
- 2d 4h
- Merged PRs (30d)
- 65
Description
KotlinSerializationJsonConvertersCustomizer gives the Kotlin Serialization converter a broad (type) -> true predicate unless one of its Jackson 3, Jackson 2, or Gson classpath checks matches. JSON-B is not among those checks:
boolean hasAnyJsonSupport = ClassUtils.isPresent("tools.jackson.databind.json.JsonMapper", classLoader)
|| ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", classLoader)
|| ClassUtils.isPresent("com.google.gson.Gson", classLoader);
When JSON-B and Kotlin Serialization are configured together without Jackson or Gson, the Kotlin converter claims every type for application/json and, being ordered ahead of JSON-B, handles non-@Serializable types that JsonbHttpMessageConverter would otherwise serialize. This doesn't match the "when no alternative JSON converter is available" intent of #48070.
Reproduction: with only kotlinx-serialization-json and a JSON-B provider on the classpath (no Jackson/Gson). With this setup, the auto-configured Kotlin converter is given its broad (type) -> true predicate and therefore reports that it can write Map as application/json, so it wins over JsonbHttpMessageConverter for non-@Serializable types. The same client and server customizer feeds MVC, RestTemplate, and RestClient; the reactive codec side has no JSON-B codec and is not affected.
This is a regression from 4.0.0 to 4.0.1. The original fix for #48070 (58cdf71) decided the predicate by scanning the registered HttpMessageConverter beans for one supporting application/json, which included JSON-B. The client/server split in 4.0.1 (50f64f) replaced that with the Jackson/Jackson2/Gson classpath check above, dropping JSON-B. It remains in 4.0.x, 4.1.x, and main.
A plain jakarta.json.bind.Jsonb classpath check needs care: JsonbAutoConfiguration requires JSON-B and JSON-P provider resources before it creates a Jsonb bean (covered by JsonbAutoConfigurationWithNoProviderTests), whereas Spring Framework's default converter detection checks for the JSON-B API alone. The API-only case therefore needs separate consideration. What is the right signal to reflect the JSON-B converter's actual availability in the Kotlin predicate?
If this direction is appropriate, I can prepare a small patch with tests covering both the active JSON-B and API-only cases.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in KotlinSerializationJsonConvertersCustomizer and compare its classpath checks with JSON-B converter availability. Read JsonbAutoConfigurationWithNoProviderTests first, then trace how the customizer feeds MVC, RestTemplate, and RestClient. Done means tests cover both an active JSON-B provider and the API-only case, without affecting reactive codecs.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, kotlin, spring-boot
- Domain
- api, backend, testing
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100