From a6b35f52167c3bb58f443f84da5105c5d4896def Mon Sep 17 00:00:00 2001 From: Tolga Akkiraz Date: Fri, 27 Mar 2026 22:03:47 +0100 Subject: [PATCH 1/2] fix(kotlin-spring): use correct Jackson 3 property path for WRITE_DATES_AS_TIMESTAMPS When using Spring Boot 4 with Jackson 3, the property path for WRITE_DATES_AS_TIMESTAMPS changed from: spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS to: spring.jackson.datatype.datetime.WRITE_DATES_AS_TIMESTAMPS This fix adds conditional logic to the kotlin-spring generator template to use the correct property path based on useSpringBoot4 flag, matching the behavior already implemented in the JavaSpring generator. Fixes binding error: 'Failed to bind properties under spring.jackson.serialization to java.util.Map: No enum constant tools.jackson.databind.SerializationFeature.WRITE_DATES_AS_TIMESTAMPS' --- .../libraries/spring-boot/application.mustache | 7 +++++++ .../src/main/resources/application.yaml | 5 +++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/modules/openapi-generator/src/main/resources/kotlin-spring/libraries/spring-boot/application.mustache b/modules/openapi-generator/src/main/resources/kotlin-spring/libraries/spring-boot/application.mustache index 9bc4fb4c27c5..f11b679920a8 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-spring/libraries/spring-boot/application.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-spring/libraries/spring-boot/application.mustache @@ -3,8 +3,15 @@ spring: name: {{title}} jackson: +{{#useSpringBoot4}} + datatype: + datetime: + WRITE_DATES_AS_TIMESTAMPS: false +{{/useSpringBoot4}} +{{^useSpringBoot4}} serialization: WRITE_DATES_AS_TIMESTAMPS: false +{{/useSpringBoot4}} server: port: {{serverPort}} diff --git a/samples/server/petstore/kotlin-springboot-4/src/main/resources/application.yaml b/samples/server/petstore/kotlin-springboot-4/src/main/resources/application.yaml index 8e2ebcde976d..c15a762036d3 100644 --- a/samples/server/petstore/kotlin-springboot-4/src/main/resources/application.yaml +++ b/samples/server/petstore/kotlin-springboot-4/src/main/resources/application.yaml @@ -3,8 +3,9 @@ spring: name: openAPIPetstore jackson: - serialization: - WRITE_DATES_AS_TIMESTAMPS: false + datatype: + datetime: + WRITE_DATES_AS_TIMESTAMPS: false server: port: 8080 From 68a77f182792c8775511021242ef6bcfb55d3077 Mon Sep 17 00:00:00 2001 From: Tolga Akkiraz Date: Fri, 27 Mar 2026 22:07:51 +0100 Subject: [PATCH 2/2] test(kotlin-spring): add tests for Jackson datetime property path Add tests to verify that: - Spring Boot 4 generates application.yaml with spring.jackson.datatype.datetime.WRITE_DATES_AS_TIMESTAMPS - Spring Boot 3 generates application.yaml with spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS --- .../spring/KotlinSpringServerCodegenTest.java | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/spring/KotlinSpringServerCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/spring/KotlinSpringServerCodegenTest.java index dc250555135b..6ddddea15b42 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/spring/KotlinSpringServerCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/spring/KotlinSpringServerCodegenTest.java @@ -676,6 +676,53 @@ public void useSpringBoot3() throws Exception { ); } + @Test(description = "Spring Boot 4 should use Jackson 3 datetime property path") + public void useSpringBoot4JacksonDateTimeProperty() throws Exception { + File output = Files.createTempDirectory("test").toFile().getCanonicalFile(); + output.deleteOnExit(); + String outputPath = output.getAbsolutePath().replace('\\', '/'); + + KotlinSpringServerCodegen codegen = new KotlinSpringServerCodegen(); + codegen.setOutputDir(output.getAbsolutePath()); + codegen.additionalProperties().put(KotlinSpringServerCodegen.USE_SPRING_BOOT4, true); + + new DefaultGenerator().opts(new ClientOptInput() + .openAPI(TestUtils.parseSpec("src/test/resources/3_0/petstore.yaml")) + .config(codegen)) + .generate(); + + // Spring Boot 4 uses Jackson 3, which moved WRITE_DATES_AS_TIMESTAMPS to + // spring.jackson.datatype.datetime instead of spring.jackson.serialization + Path applicationYaml = Paths.get(outputPath + "/src/main/resources/application.yaml"); + assertFileContains(applicationYaml, "datatype:"); + assertFileContains(applicationYaml, "datetime:"); + assertFileContains(applicationYaml, "WRITE_DATES_AS_TIMESTAMPS: false"); + assertFileNotContains(applicationYaml, "serialization:"); + } + + @Test(description = "Spring Boot 3 should use Jackson 2 serialization property path") + public void useSpringBoot3JacksonSerializationProperty() throws Exception { + File output = Files.createTempDirectory("test").toFile().getCanonicalFile(); + output.deleteOnExit(); + String outputPath = output.getAbsolutePath().replace('\\', '/'); + + KotlinSpringServerCodegen codegen = new KotlinSpringServerCodegen(); + codegen.setOutputDir(output.getAbsolutePath()); + codegen.additionalProperties().put(KotlinSpringServerCodegen.USE_SPRING_BOOT3, true); + + new DefaultGenerator().opts(new ClientOptInput() + .openAPI(TestUtils.parseSpec("src/test/resources/3_0/petstore.yaml")) + .config(codegen)) + .generate(); + + // Spring Boot 3 uses Jackson 2, which has WRITE_DATES_AS_TIMESTAMPS under + // spring.jackson.serialization + Path applicationYaml = Paths.get(outputPath + "/src/main/resources/application.yaml"); + assertFileContains(applicationYaml, "serialization:"); + assertFileContains(applicationYaml, "WRITE_DATES_AS_TIMESTAMPS: false"); + assertFileNotContains(applicationYaml, "datatype:"); + } + @Test(description = "multi-line descriptions should be supported for operations") public void multiLineOperationDescription() throws IOException { testMultiLineOperationDescription(false);