Skip to content

feat(kotlin-spring): add Spring Boot 4 and Jackson 3 support#23154

Merged
wing328 merged 21 commits intoOpenAPITools:masterfrom
yonatankarp:feat/kotlin-spring-boot4-jackson3
Mar 10, 2026
Merged

feat(kotlin-spring): add Spring Boot 4 and Jackson 3 support#23154
wing328 merged 21 commits intoOpenAPITools:masterfrom
yonatankarp:feat/kotlin-spring-boot4-jackson3

Conversation

@yonatankarp
Copy link
Contributor

@yonatankarp yonatankarp commented Mar 6, 2026

Add useSpringBoot4 and useJackson3 options to the Kotlin Spring generator, mirroring the existing Java Spring support (merged in 5a70edb0630).

Jackson 3 infrastructure (jacksonPackage template variable, applyJackson2Package()/applyJackson3Package() methods) is placed in AbstractKotlinCodegen for reuse across all Kotlin generators. Spring Boot 4 logic (flag, constraints, template selection) lives in KotlinSpringServerCodegen.

Codegen changes:

  • AbstractKotlinCodegen.javaUSE_JACKSON_3 constant, useJackson3 field, applyJackson2Package()/applyJackson3Package() methods, processOpts() handling
  • KotlinSpringServerCodegen.javaUSE_SPRING_BOOT4 constant, useSpringBoot4 field, constraint validation, template selection for SB4

New templates (6 files):

  • pom-sb4.mustache and buildGradle-sb4-Kts.mustache for spring-boot, spring-cloud, and spring-declarative-http-interface libraries

Dependency versions (SB4):

  • Spring Boot 4.0.1, Kotlin 2.2.0, Jakarta Annotation 3.0.0
  • Jackson 3: tools.jackson.* group IDs (when useJackson3=true)
  • Jackson 2: com.fasterxml.jackson.* still works with SB4 (when useJackson3=false)

Constraints enforced:

  • useSpringBoot3 and useSpringBoot4 are mutually exclusive
  • useJackson3 requires useSpringBoot4
  • useJackson3 is incompatible with openApiNullable
  • useSpringBoot4 auto-enables useJakartaEe
  • SpringFox and Swagger 1 annotations rejected with SB4

Tests (6 new):

  • Constraint validation: refuse Jackson 3 without SB4, refuse SB3+SB4, refuse openApiNullable+Jackson 3
  • Generated code assertions: Jakarta imports with SB4, POM with Jackson 3 deps, POM with Jackson 2 deps

Sample: samples/server/petstore/kotlin-springboot-4/ — non-reactive Spring Boot 4 with Jackson 3, added to JDK17 CI matrix.

PR checklist

  • Read the contribution guidelines.
  • Pull Request title clearly describes the work in the pull request and Pull Request description provides details about how to validate the work. Missing information here may result in delayed response from the community.
  • Run the following to build the project and update samples:
    ./mvnw clean package || exit
    ./bin/generate-samples.sh ./bin/configs/*.yaml || exit
    ./bin/utils/export_docs_generators.sh || exit
    
    Commit all changed files.
  • File the PR against the correct branch: master (upcoming 7.x.0 minor release - breaking changes with fallbacks)
  • 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 @dennisameling

Closes #23098


Summary by cubic

Adds Spring Boot 4 and Jackson 3 support to the Kotlin Spring server generator. SB4 always uses Jackson 3, with new templates, docs, and a sample added to CI.

  • New Features

    • Added useSpringBoot4/useJackson3 with validation: SB3 vs SB4 are exclusive; useJackson3 requires SB4, defaults to true with SB4, and is incompatible with openApiNullable; SB4 auto-enables Jakarta EE and rejects SpringFox/Swagger 1.
    • Centralized Jackson 2/3 selection via jacksonPackage in AbstractKotlinCodegen; useJackson3 exposed in CLI/docs (kotlin-spring and kotlin). kotlin-client registers useJackson3 but throws a clear error (client support later). Jackson 3 uses tools.jackson.*; Jackson 2 remains available as com.fasterxml.jackson.* (not with SB4).
    • SB4 templates for spring-boot, spring-cloud, and spring-declarative-http-interface (Maven and Gradle KTS), using Spring Boot 4.0.1, Kotlin 2.2, and Gradle 8.14; switched to spring-boot-starter-oauth2-client.
    • New non-reactive SB4 + Jackson 3 sample and tests for constraints, dependency selection, Jakarta imports, and Jackson 2 vs 3 exclusivity; sample added to JDK17 CI.
  • Bug Fixes

    • Spring Cloud (SB4) uses modern OAuth2 client config (OAuth2AuthorizedClientManager) instead of legacy classes.
    • Always declare springdoc-openapi.version even when useSwaggerUI=false; add trailing newline to spring-cloud/clientConfiguration.mustache.
    • Default Jackson 3 when SB4 is set via setter; update Gradle templates to Kotlin 2.2 compilerOptions DSL; wrappers/CI use Gradle 8.14.
    • Removed invalid SB4+Jackson2 test; SB4 unconditionally implies Jackson 3.

Written for commit 8dd6ea8. Summary will update on new commits.

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4 issues found across 46 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="samples/server/petstore/kotlin-springboot-4/src/main/kotlin/org/openapitools/api/StoreApiController.kt">

<violation number="1" location="samples/server/petstore/kotlin-springboot-4/src/main/kotlin/org/openapitools/api/StoreApiController.kt:39">
P1: `deleteOrder` unconditionally returns HTTP 400, so even successful deletions are reported as client errors.</violation>
</file>

<file name="samples/server/petstore/kotlin-springboot-4/build.gradle.kts">

<violation number="1" location="samples/server/petstore/kotlin-springboot-4/build.gradle.kts:3">
P1: `plugins {}` is declared after other top-level statements in `build.gradle.kts`, which can break Gradle Kotlin DSL script evaluation.</violation>
</file>

<file name="samples/server/petstore/kotlin-springboot-4/src/main/kotlin/org/openapitools/api/PetApiService.kt">

<violation number="1" location="samples/server/petstore/kotlin-springboot-4/src/main/kotlin/org/openapitools/api/PetApiService.kt:103">
P2: Optional multipart `file` is declared non-null, conflicting with optional request-part semantics and OpenAPI contract.</violation>
</file>

<file name="modules/openapi-generator/src/main/resources/kotlin-spring/libraries/spring-cloud/pom-sb4.mustache">

<violation number="1" location="modules/openapi-generator/src/main/resources/kotlin-spring/libraries/spring-cloud/pom-sb4.mustache:146">
P2: When `useSwaggerUI=false`, the POM references the removed `springdoc-openapi-*-core` artifacts. In springdoc-openapi v2, these were renamed to `springdoc-openapi-starter-*-api`, so this dependency will fail to resolve for v2.x (e.g., 2.8.6).</violation>
</file>

Since this is your first cubic review, here's how it works:

  • cubic automatically reviews your code and comments on bugs and improvements
  • Teach cubic by replying to its comments. cubic learns from your replies and gets better over time
  • Add one-off context when rerunning by tagging @cubic-dev-ai with guidance or docs links (including llms.txt)
  • Ask questions if you need clarification on any suggestion

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

9 issues found across 67 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="samples/client/petstore/kotlin-jackson3/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt">

<violation number="1">
P2: Authorization Bearer header is built with a trailing space, which can invalidate token authentication.</violation>
</file>

<file name="modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-retrofit2/infrastructure/ApiClient.kt.mustache">

<violation number="1">
P2: JacksonConverterFactory expects a Jackson 2 ObjectMapper, but the template now imports {{jacksonPackage}}.databind.ObjectMapper. When jacksonPackage=tools.jackson (Jackson 3), JacksonConverterFactory.create(serializerBuilder) will not compile due to a type mismatch.</violation>
</file>

<file name="samples/client/petstore/kotlin-jackson3/docs/UserApi.md">

<violation number="1">
P2: The loginUser parameter table is malformed because a data row appears before the header row, which breaks Markdown table rendering.</violation>
</file>

<file name="modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-ktor/infrastructure/ApiClient.kt.mustache">

<violation number="1">
P2: The Ktor jackson plugin expects com.fasterxml.jackson.databind.ObjectMapper, but this template now switches ObjectMapper imports to {{jacksonPackage}} (tools.jackson when useJackson3), causing a type mismatch in the jackson { ... } configuration block and breaking compilation for jvm-ktor clients with useJackson3 enabled.</violation>
</file>

<file name="samples/client/petstore/kotlin-jackson3/docs/PetApi.md">

<violation number="1">
P2: Parameter tables are malformed because rows are emitted before the header/separator, which breaks Markdown table rendering for the parameters.</violation>
</file>

<file name="samples/client/petstore/kotlin-jackson3/docs/Order.md">

<violation number="1">
P3: Dead local link: java.time.OffsetDateTime.md does not exist in this docs set, so the shipDate type link is broken.</violation>
</file>

<file name="samples/client/petstore/kotlin-jackson3/src/main/kotlin/org/openapitools/client/infrastructure/ResponseExtensions.kt">

<violation number="1">
P3: `Response.isRedirect` extension is shadowed by OkHttp’s member property, so the 300..399 helper is never used and `it.isRedirect` in ApiClient resolves to OkHttp’s built‑in behavior instead.</violation>
</file>

<file name="modules/openapi-generator/src/main/resources/kotlin-client/anyof_class.mustache">

<violation number="1">
P2: Jackson 3 keeps annotations in com.fasterxml.jackson.annotation, so using {{jacksonPackage}}.annotation.* breaks generated code when jacksonPackage=tools.jackson.</violation>
</file>

<file name="modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-spring-restclient/api.mustache">

<violation number="1">
P2: Jackson 3 mode still uses `MappingJackson2HttpMessageConverter` (Jackson 2–specific, deprecated in Spring 7), so generated clients can fail when `jacksonPackage` is set to `tools.jackson`. The converter should be updated or conditional for Jackson 3.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

@yonatankarp yonatankarp marked this pull request as draft March 7, 2026 07:42
@yonatankarp yonatankarp force-pushed the feat/kotlin-spring-boot4-jackson3 branch 4 times, most recently from f71ec52 to 6d634e9 Compare March 7, 2026 16:00
@yonatankarp yonatankarp marked this pull request as ready for review March 7, 2026 16:01
@yonatankarp yonatankarp force-pushed the feat/kotlin-spring-boot4-jackson3 branch from 6d634e9 to 02d33fd Compare March 7, 2026 16:02
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

9 issues found across 51 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="samples/server/petstore/kotlin-springboot-4/build.gradle.kts">

<violation number="1" location="samples/server/petstore/kotlin-springboot-4/build.gradle.kts:17">
P2: The `plugins {}` block is placed after other top‑level statements (`group`, `version`, `repositories`, `kotlin`), which violates Gradle Kotlin DSL ordering rules and will cause script compilation to fail. Move `plugins {}` to the top (after imports) before other configuration blocks.</violation>
</file>

<file name="modules/openapi-generator/src/main/resources/kotlin-spring/libraries/spring-declarative-http-interface/buildGradle-sb4-Kts.mustache">

<violation number="1" location="modules/openapi-generator/src/main/resources/kotlin-spring/libraries/spring-declarative-http-interface/buildGradle-sb4-Kts.mustache:17">
P2: `plugins {}` block is placed after other top-level configuration statements. In Gradle Kotlin DSL, `plugins` must appear before other blocks (except imports/buildscript/pluginManagement), otherwise the build script can fail to compile.</violation>
</file>

<file name="modules/openapi-generator/src/main/resources/kotlin-spring/libraries/spring-boot/pom-sb4.mustache">

<violation number="1" location="modules/openapi-generator/src/main/resources/kotlin-spring/libraries/spring-boot/pom-sb4.mustache:128">
P2: springdoc-openapi.version is only declared when useSwaggerUI is true, but the SpringDoc core dependency (useSwaggerUI=false) still references it, yielding an undefined Maven property.</violation>
</file>

<file name="samples/server/petstore/kotlin-springboot-4/src/main/kotlin/org/openapitools/api/PetApiController.kt">

<violation number="1" location="samples/server/petstore/kotlin-springboot-4/src/main/kotlin/org/openapitools/api/PetApiController.kt:138">
P2: `file` is marked optional (`required = false`) but declared non‑nullable, so missing multipart parts will be passed as null and Kotlin will throw before the handler runs, making the optional part effectively required.</violation>
</file>

<file name="modules/openapi-generator/src/main/resources/kotlin-spring/libraries/spring-cloud/buildGradle-sb4-Kts.mustache">

<violation number="1" location="modules/openapi-generator/src/main/resources/kotlin-spring/libraries/spring-cloud/buildGradle-sb4-Kts.mustache:3">
P2: `plugins {}` block is placed after other top-level statements, but Gradle requires it to appear before any other blocks in `build.gradle.kts`, which can cause script parsing errors.</violation>

<violation number="2" location="modules/openapi-generator/src/main/resources/kotlin-spring/libraries/spring-cloud/buildGradle-sb4-Kts.mustache:69">
P2: Legacy `spring-cloud-starter-oauth2:2.2.5.RELEASE` is hardcoded in the SB4 template, but this starter is a deprecated bridge for Boot 1.x/2.x and is discontinued. Pinning this old version bypasses the Spring Cloud BOM and is incompatible with Boot 4/Spring Cloud 2025 (Jakarta-based), risking dependency conflicts or missing classes.</violation>
</file>

<file name="modules/openapi-generator/src/main/resources/kotlin-spring/libraries/spring-declarative-http-interface/pom-sb4.mustache">

<violation number="1" location="modules/openapi-generator/src/main/resources/kotlin-spring/libraries/spring-declarative-http-interface/pom-sb4.mustache:179">
P2: The SB4 template still injects legacy `spring-cloud-starter-oauth2` and hard‑pins it to `2.2.5.RELEASE`, which is pre‑Jakarta and EOL. In a Spring Boot 4/Jakarta 11 project this is likely to cause dependency resolution or binary incompatibility failures when auth is enabled.</violation>
</file>

<file name="modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/spring/KotlinSpringServerCodegenTest.java">

<violation number="1" location="modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/spring/KotlinSpringServerCodegenTest.java:4839">
P2: Jackson dependency tests do not assert exclusivity between Jackson 2 and Jackson 3 coordinates, so a POM with both families would still pass. Add negative assertions to ensure the opposite Jackson family is absent in each mode.</violation>
</file>

<file name="samples/server/petstore/kotlin-springboot-4/src/main/kotlin/org/openapitools/api/UserApiController.kt">

<violation number="1" location="samples/server/petstore/kotlin-springboot-4/src/main/kotlin/org/openapitools/api/UserApiController.kt:78">
P2: deleteUser and updateUser always return HTTP 400 even on successful execution, causing successful operations to be reported as client errors.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 5 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="modules/openapi-generator/src/main/resources/kotlin-spring/libraries/spring-cloud/buildGradle-sb4-Kts.mustache">

<violation number="1" location="modules/openapi-generator/src/main/resources/kotlin-spring/libraries/spring-cloud/buildGradle-sb4-Kts.mustache:69">
P1: SB4 spring-cloud dependency was migrated to `spring-boot-starter-oauth2-client` while generated auth templates still use legacy OAuth2 Feign/context classes, creating a compile-time mismatch for auth-enabled clients.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 3 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinSpringServerCodegen.java">

<violation number="1" location="modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinSpringServerCodegen.java:424">
P2: `useJackson3` defaulting is only tied to `additionalProperties`, so enabling Spring Boot 4 via setter/API can skip the intended Jackson 3 default.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

@yonatankarp yonatankarp marked this pull request as draft March 7, 2026 22:45
…SL and bump CI Gradle

- Replace deprecated kotlinOptions.jvmTarget with kotlin.compilerOptions DSL
- Upgrade Gradle wrapper to 8.14 for Kotlin 2.2 compatibility
- Add kotlin-springboot-4 sample to JDK17 CI matrix
- Regenerate sample with updated templates
…14 for SB4

- Add addSwitch for useJackson3 in KotlinSpringServerCodegen so it
  appears in auto-generated docs
- Update gradle-wrapper.properties.mustache templates to use Gradle 8.14
  when useSpringBoot4 is enabled (required minimum for Spring Boot 4)
…-restclient support

Replace hardcoded com.fasterxml.jackson imports with {{jacksonPackage}} template
variable across all kotlin-client templates so generated code compiles correctly
when useJackson3=true. Also fix trailing space in OAuth Bearer header, enable
useJackson3 for jvm-ktor (Ktor 3.4.0) and jvm-spring-restclient (Spring Boot 4),
and add conditional Jackson 3 dependencies in build.gradle.
…r/spring-restclient support"

Block useJackson3 for kotlin-client with a clear error until client
template support is added in a follow-up PR.
…lusivity tests

Replace deprecated spring-cloud-starter-oauth2:2.2.5.RELEASE with
spring-boot-starter-oauth2-client in SB4 templates, as the legacy
starter is pre-Jakarta and incompatible with Spring Boot 4.

Add negative assertions to Jackson dependency tests to ensure Jackson 2
and Jackson 3 artifacts are mutually exclusive.
Spring Boot 4 ships with Jackson 3 out of the box, so useJackson3 now
defaults to true when useSpringBoot4 is enabled and the user hasn't
explicitly set useJackson3.
…useSwaggerUI

The springdoc-openapi.version Maven property was only declared when
useSwaggerUI=true, but the springdoc core dependency (used when
useSwaggerUI=false) also references it, causing an undefined property.
… spring-cloud library

Add useSpringBoot4 conditionals to clientConfiguration.mustache so SB4
uses OAuth2AuthorizedClientManager instead of legacy OAuth2FeignRequestInterceptor
and *ResourceDetails classes that don't exist in Spring Boot 4.
…er or additionalProperties

The Jackson 3 defaulting logic only checked additionalProperties map,
so calling setUseSpringBoot4(true) via the Java API skipped the default.
Now checks both the field value and the map.
@yonatankarp yonatankarp force-pushed the feat/kotlin-spring-boot4-jackson3 branch from 402546a to 6fcc1dd Compare March 9, 2026 15:14
@yonatankarp yonatankarp marked this pull request as ready for review March 9, 2026 16:24
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

13 issues found across 52 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="modules/openapi-generator/src/main/resources/kotlin-spring/libraries/spring-boot/buildGradle-sb4-Kts.mustache">

<violation number="1" location="modules/openapi-generator/src/main/resources/kotlin-spring/libraries/spring-boot/buildGradle-sb4-Kts.mustache:23">
P2: `plugins {}` block appears after other top-level statements. Gradle Kotlin DSL requires the plugins block to be first (before repositories, group/version, etc.), otherwise the script is rejected.</violation>
</file>

<file name="samples/server/petstore/kotlin-springboot-4/src/main/kotlin/org/openapitools/api/PetApiService.kt">

<violation number="1" location="samples/server/petstore/kotlin-springboot-4/src/main/kotlin/org/openapitools/api/PetApiService.kt:103">
P2: Optional multipart `file` parameter is generated as non-null, which mismatches the endpoint’s optional contract and may reject valid requests with no file part.</violation>
</file>

<file name="samples/server/petstore/kotlin-springboot-4/build.gradle.kts">

<violation number="1" location="samples/server/petstore/kotlin-springboot-4/build.gradle.kts:17">
P2: `plugins {}` block is not first in the build script. Gradle Kotlin DSL requires the plugins block to appear before other top-level statements (except `buildscript {}`), otherwise the script can fail to compile/evaluate.</violation>
</file>

<file name="samples/server/petstore/kotlin-springboot-4/src/test/kotlin/org/openapitools/api/StoreApiTest.kt">

<violation number="1" location="samples/server/petstore/kotlin-springboot-4/src/test/kotlin/org/openapitools/api/StoreApiTest.kt:51">
P2: Active JUnit test methods contain `TODO()` placeholders, making generated tests non-executable and non-validating at runtime.</violation>
</file>

<file name="modules/openapi-generator/src/main/resources/kotlin-spring/libraries/spring-cloud/buildGradle-sb4-Kts.mustache">

<violation number="1" location="modules/openapi-generator/src/main/resources/kotlin-spring/libraries/spring-cloud/buildGradle-sb4-Kts.mustache:3">
P1: Generated Gradle Kotlin DSL template places regular top-level statements before `plugins {}`, which can break build script evaluation.</violation>
</file>

<file name="samples/server/petstore/kotlin-springboot-4/pom.xml">

<violation number="1" location="samples/server/petstore/kotlin-springboot-4/pom.xml:115">
P2: Bean Validation API is declared without a validator implementation (e.g., `spring-boot-starter-validation`), so `@Valid`/constraint annotations may not be enforced at runtime under Boot 4.</violation>
</file>

<file name="modules/openapi-generator/src/main/resources/kotlin-spring/libraries/spring-declarative-http-interface/buildGradle-sb4-Kts.mustache">

<violation number="1" location="modules/openapi-generator/src/main/resources/kotlin-spring/libraries/spring-declarative-http-interface/buildGradle-sb4-Kts.mustache:17">
P1: `plugins {}` is declared after other top-level statements in a Kotlin DSL build script template, which can make generated `build.gradle.kts` fail to evaluate.</violation>
</file>

<file name="samples/server/petstore/kotlin-springboot-4/src/main/kotlin/org/openapitools/api/PetApiController.kt">

<violation number="1" location="samples/server/petstore/kotlin-springboot-4/src/main/kotlin/org/openapitools/api/PetApiController.kt:138">
P2: Optional multipart part is marked required=false but typed as non-null MultipartFile; when the part is omitted, Spring supplies null and Kotlin null-check will fail. Make the parameter nullable (or mark required=true) to avoid binding errors for omitted files.</violation>
</file>

<file name="modules/openapi-generator/src/main/resources/kotlin-spring/libraries/spring-cloud/clientConfiguration.mustache">

<violation number="1" location="modules/openapi-generator/src/main/resources/kotlin-spring/libraries/spring-cloud/clientConfiguration.mustache:157">
P2: SB4 OAuth2 interceptor is only created when a non-standard `registration.<id>.enabled=true` property is set, so standard OAuth2 client configuration (client-id/client-secret) will silently disable auth.</violation>

<violation number="2" location="modules/openapi-generator/src/main/resources/kotlin-spring/libraries/spring-cloud/clientConfiguration.mustache:158">
P2: SB4 OAuth bean/constant names are flow-only, so multiple OAuth schemes using the same flow will generate duplicate method/constant names in ClientConfiguration and fail compilation.</violation>
</file>

<file name="modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinSpringServerCodegen.java">

<violation number="1" location="modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinSpringServerCodegen.java:431">
P2: Auto-defaulting USE_JACKSON_3 to true before super.processOpts() overwrites explicit setter-based useJackson3=false in programmatic integrations, forcing Jackson 3 even when callers opt out without additionalProperties.</violation>
</file>

<file name="modules/openapi-generator/src/main/resources/kotlin-spring/libraries/spring-cloud/pom-sb4.mustache">

<violation number="1" location="modules/openapi-generator/src/main/resources/kotlin-spring/libraries/spring-cloud/pom-sb4.mustache:139">
P1: Reactive SpringDoc Swagger UI artifactId template inserts newline/indent into Maven coordinate, which can produce an invalid dependency artifactId and break generated builds.</violation>

<violation number="2" location="modules/openapi-generator/src/main/resources/kotlin-spring/libraries/spring-cloud/pom-sb4.mustache:146">
P2: The SpringDoc no-UI dependency is using the `...-core` artifact, which isn’t published/used in SpringDoc 2.x; it should use `springdoc-openapi-starter-...-api` to avoid dependency resolution failures.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

@Picazsoo
Copy link
Contributor

Picazsoo commented Mar 9, 2026

Once merged, this fixes #23098

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 1 file (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinSpringServerCodegen.java">

<violation number="1" location="modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinSpringServerCodegen.java:430">
P2: When Spring Boot 4 is enabled, the generator now always forces `useJackson3=true`, overwriting explicit user configuration (e.g., `useJackson3=false`). This turns a default into a hard override and changes generated dependencies/validation behavior even when users opted out of Jackson 3.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

…y implies Jackson 3

Spring Boot 4 ships with Jackson 3 — there is no supported SB4+Jackson2
combination, so the test was asserting an invalid scenario.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 1 file (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/spring/KotlinSpringServerCodegenTest.java">

<violation number="1" location="modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/spring/KotlinSpringServerCodegenTest.java:4877">
P2: Deleting this test removes the only Kotlin Spring regression coverage for Spring Boot 4 with `useJackson3=false` (Jackson 2 dependency output).</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

@wing328
Copy link
Member

wing328 commented Mar 10, 2026

looks good

let's give it a try

@wing328 wing328 merged commit a04b9a5 into OpenAPITools:master Mar 10, 2026
63 checks passed
@yonatankarp yonatankarp deleted the feat/kotlin-spring-boot4-jackson3 branch March 10, 2026 08:57
davidricodias pushed a commit to davidricodias/openapi-generator that referenced this pull request Mar 11, 2026
…Tools#23154)

* feat(kotlin): add Jackson 3 infrastructure to AbstractKotlinCodegen

* feat(kotlin-spring): add useSpringBoot4 and useJackson3 flags

* feat(kotlin-spring): update template selection for Spring Boot 4

* feat(kotlin-spring): add SB4 templates for all libraries

* test(kotlin-spring): add tests for Spring Boot 4 and Jackson 3 support

* feat(kotlin-spring): add kotlin-springboot-4 sample with Jackson 3

* docs(kotlin-spring): document useSpringBoot4 and useJackson3 options

* fix(kotlin-spring): update Gradle templates to Kotlin 2.2 JvmTarget DSL and bump CI Gradle

- Replace deprecated kotlinOptions.jvmTarget with kotlin.compilerOptions DSL
- Upgrade Gradle wrapper to 8.14 for Kotlin 2.2 compatibility
- Add kotlin-springboot-4 sample to JDK17 CI matrix
- Regenerate sample with updated templates

* fix(kotlin-spring): register useJackson3 CLI option and use Gradle 8.14 for SB4

- Add addSwitch for useJackson3 in KotlinSpringServerCodegen so it
  appears in auto-generated docs
- Update gradle-wrapper.properties.mustache templates to use Gradle 8.14
  when useSpringBoot4 is enabled (required minimum for Spring Boot 4)

* fix(kotlin-client): fix Jackson 3 package imports and add ktor/spring-restclient support

Replace hardcoded com.fasterxml.jackson imports with {{jacksonPackage}} template
variable across all kotlin-client templates so generated code compiles correctly
when useJackson3=true. Also fix trailing space in OAuth Bearer header, enable
useJackson3 for jvm-ktor (Ktor 3.4.0) and jvm-spring-restclient (Spring Boot 4),
and add conditional Jackson 3 dependencies in build.gradle.

* Revert "fix(kotlin-client): fix Jackson 3 package imports and add ktor/spring-restclient support"

Block useJackson3 for kotlin-client with a clear error until client
template support is added in a follow-up PR.

* ci: retrigger CI checks

* fix(kotlin-spring): replace legacy oauth2 starter and add Jackson exclusivity tests

Replace deprecated spring-cloud-starter-oauth2:2.2.5.RELEASE with
spring-boot-starter-oauth2-client in SB4 templates, as the legacy
starter is pre-Jakarta and incompatible with Spring Boot 4.

Add negative assertions to Jackson dependency tests to ensure Jackson 2
and Jackson 3 artifacts are mutually exclusive.

* feat(kotlin-spring): default to Jackson 3 when Spring Boot 4 is enabled

Spring Boot 4 ships with Jackson 3 out of the box, so useJackson3 now
defaults to true when useSpringBoot4 is enabled and the user hasn't
explicitly set useJackson3.

* fix(kotlin-spring): declare springdoc version property regardless of useSwaggerUI

The springdoc-openapi.version Maven property was only declared when
useSwaggerUI=true, but the springdoc core dependency (used when
useSwaggerUI=false) also references it, causing an undefined property.

* fix(kotlin-spring): use modern OAuth2 client config for Spring Boot 4 spring-cloud library

Add useSpringBoot4 conditionals to clientConfiguration.mustache so SB4
uses OAuth2AuthorizedClientManager instead of legacy OAuth2FeignRequestInterceptor
and *ResourceDetails classes that don't exist in Spring Boot 4.

* fix(kotlin-spring): default Jackson 3 when Spring Boot 4 set via setter or additionalProperties

The Jackson 3 defaulting logic only checked additionalProperties map,
so calling setUseSpringBoot4(true) via the Java API skipped the default.
Now checks both the field value and the map.

* fix(kotlin-spring): add trailing newline to clientConfiguration template

* Trigger CI

* clean up conditions

* fix(kotlin-spring): remove SB4+Jackson2 test since SB4 unconditionally implies Jackson 3

Spring Boot 4 ships with Jackson 3 — there is no supported SB4+Jackson2
combination, so the test was asserting an invalid scenario.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[REQ][kotlin-spring] spring boot 4 + jackson3 support

4 participants