[kotlin][client] Support useJackson3 for the jvm-ktor library

DE
9h ago
+4025-3

This extends the approach of #24709 (Jackson 3 for jvm-okhttp4 and jvm-spring-restclient) to the jvm-ktor library.

Today the codegen rejects useJackson3 for jvm-ktor, and the jvm-ktor templates hard-code Jackson 2 (com.fasterxml.jackson) in ApiClient and in the API classes.

Changes:

  • KotlinClientCodegen: allow useJackson3 with library=jvm-ktor.
  • jvm-ktor/infrastructure/ApiClient.kt.mustache and jvm-ktor/api.mustache: with useJackson3, the generated code imports tools.jackson and io.ktor.serialization.jackson3, and jsonBlock becomes JsonMapper.Builder.() -> Unit. Jackson 3 mappers are immutable and configured through a builder, so the parameter type changes. JavaTimeModule is not registered, because Jackson 3 databind supports java.time itself.
  • build.gradle.mustache: with useJackson3, jvm-ktor depends on ktor-serialization-jackson3 instead of ktor-client-jackson and ktor-serialization-jackson.
  • New sample samples/client/petstore/kotlin-jvm-ktor-jackson3, added to the Kotlin client samples workflow.
  • Tests for the Jackson 3 output and for the unchanged Jackson 2 default.

Without useJackson3, the generated code does not change.

Note for users who switch: the Jackson 2 JSON_DEFAULT writes OffsetDateTime as an epoch number, because WRITE_DATES_AS_TIMESTAMPS is on by default in Jackson 2. Jackson 3 writes ISO-8601 strings by default, which matches format: date-time.

Tested:

  • KotlinClientCodegenModelTest and KotlinClientCodegenApiTest: 111 tests, 0 failures.
  • ./bin/generate-samples.sh bin/configs/kotlin* (130 configs): the only output change is the new sample.
  • ./bin/utils/export_docs_generators.sh: no change.
  • ./gradlew build -x test in the new sample: passes.
  • A client generated from a larger real-world spec with these templates compiles against Jackson 3.3.0 and ktor 3.6.1 and made a successful live GET request.

Notes on the automated review:

  • The new sample's docs/ is identical to the existing kotlin-jvm-ktor-jackson sample (diff -r is empty). The doc-example issues come from the shared jvm-ktor docs templates, which this PR does not change.
  • The new sample is in the default (Java 11) matrix, like kotlin-jackson3 and kotlin-jvm-spring-4-restclient-jackson3. The CI step compiles only (./gradlew build -x test), and those samples pass there on master. I can move all three to a Java 17 entry if you prefer.

PR checklist

  • Read the contribution guidelines.
  • Run the following to build the project and update samples. I built with ./mvnw install -DskipTests plus the Kotlin codegen tests above, and regenerated only the Kotlin samples (bin/configs/kotlin*), because only Kotlin templates changed:
    ./mvnw clean package || exit
    ./bin/generate-samples.sh ./bin/configs/*.yaml || exit
    ./bin/utils/export_docs_generators.sh || exit
    
    Commit all changed files.
  • If your PR is targeting a particular programming language, @mention the technical committee members, so they are more likely to review the pull request.

cc @karismann @Zomzog @andrewemery @4brunu @yutaka0m @stefankoppier @e5l @AndreyVMarkelov