From 1282db025e6c0bd2471868b79179e6e381abf0f4 Mon Sep 17 00:00:00 2001 From: Dominic Fellbaum Date: Fri, 13 Mar 2026 18:57:53 +0100 Subject: [PATCH 1/3] Add support for JSpecify annotations in SpringCodegen - Introduced `useJSpecify` flag to enable the use of JSpecify's `@Nullable` annotations. - Modified POJO templates to correctly place JSpecify annotations for `TYPE_USE` compatibility. - Updated importMappings to handle hardcoded JSpecify annotations when enabled. - Added a test case for verifying correct annotation placement and behavior (`issue_23206.yaml` and corresponding Java test). --- docs/generators/java-camel.md | 1 + docs/generators/spring.md | 1 + .../codegen/languages/SpringCodegen.java | 43 ++++++++++++++++++- .../main/resources/JavaSpring/pojo.mustache | 10 ++--- .../java/spring/SpringCodegenTest.java | 31 +++++++++++++ .../resources/3_0/spring/issue_23206.yaml | 28 ++++++++++++ 6 files changed, 108 insertions(+), 6 deletions(-) create mode 100644 modules/openapi-generator/src/test/resources/3_0/spring/issue_23206.yaml diff --git a/docs/generators/java-camel.md b/docs/generators/java-camel.md index b71808af91c3..3cc4c707399c 100644 --- a/docs/generators/java-camel.md +++ b/docs/generators/java-camel.md @@ -109,6 +109,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl |useEnumCaseInsensitive|Use `equalsIgnoreCase` when String for enum comparison| |false| |useFeignClientContextId|Whether to generate Feign client with contextId parameter.| |true| |useFeignClientUrl|Whether to generate Feign client with url parameter.| |true| +|useJSpecify|Use JSpecify's @Nullable (org.jspecify.annotations.Nullable) instead of Spring's @Nullable. Overrides any user-supplied importMapping for 'Nullable'.| |false| |useJackson3|Set it in order to use jackson 3 dependencies (only allowed when `useSpringBoot4` is set and incompatible with `openApiNullable`).| |false| |useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false| |useOneOfInterfaces|whether to use a java interface to describe a set of oneOf options, where each option is a class that implements the interface| |true| diff --git a/docs/generators/spring.md b/docs/generators/spring.md index 08649ac0e6a5..a37b6ad4302d 100644 --- a/docs/generators/spring.md +++ b/docs/generators/spring.md @@ -102,6 +102,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl |useEnumCaseInsensitive|Use `equalsIgnoreCase` when String for enum comparison| |false| |useFeignClientContextId|Whether to generate Feign client with contextId parameter.| |true| |useFeignClientUrl|Whether to generate Feign client with url parameter.| |true| +|useJSpecify|Use JSpecify's @Nullable (org.jspecify.annotations.Nullable) instead of Spring's @Nullable. Overrides any user-supplied importMapping for 'Nullable'.| |false| |useJackson3|Set it in order to use jackson 3 dependencies (only allowed when `useSpringBoot4` is set and incompatible with `openApiNullable`).| |false| |useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false| |useOneOfInterfaces|whether to use a java interface to describe a set of oneOf options, where each option is a class that implements the interface| |true| diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java index d64785a8027c..bd39f8e3677a 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java @@ -109,6 +109,7 @@ public class SpringCodegen extends AbstractJavaCodegen public static final String JACKSON3_PACKAGE = "tools.jackson"; public static final String JACKSON_PACKAGE = "jacksonPackage"; public static final String ADDITIONAL_NOT_NULL_ANNOTATIONS = "additionalNotNullAnnotations"; + public static final String USE_JSPECIFY = "useJSpecify"; @Getter public enum RequestMappingMode { @@ -183,6 +184,8 @@ public enum RequestMappingMode { protected boolean useJackson3 = false; @Getter @Setter protected boolean additionalNotNullAnnotations = false; + @Getter @Setter + protected boolean useJSpecify = false; public SpringCodegen() { super(); @@ -330,6 +333,10 @@ public SpringCodegen() { cliOptions.add(CliOption.newBoolean(ADDITIONAL_NOT_NULL_ANNOTATIONS, "Add @NotNull to path variables (required by default) and requestBody.", additionalNotNullAnnotations)); + cliOptions.add(CliOption.newBoolean(USE_JSPECIFY, + "Use JSpecify's @Nullable (org.jspecify.annotations.Nullable) instead of Spring's @Nullable. " + + "Overrides any user-supplied importMapping for 'Nullable'.", + isUseJSpecify())); } @@ -545,16 +552,21 @@ public void processOpts() { convertPropertyToStringAndWriteBack(RESOURCE_FOLDER, this::setResourceFolder); convertPropertyToBooleanAndWriteBack(ADDITIONAL_NOT_NULL_ANNOTATIONS, this::setAdditionalNotNullAnnotations); + convertPropertyToBooleanAndWriteBack(USE_JSPECIFY, this::setUseJSpecify); // override parent one importMapping.put("JsonDeserialize", (useJackson3 ? JACKSON3_PACKAGE : JACKSON2_PACKAGE) + ".databind.annotation.JsonDeserialize"); typeMapping.put("file", "org.springframework.core.io.Resource"); - importMapping.put("Nullable", "org.springframework.lang.Nullable"); importMapping.put("org.springframework.core.io.Resource", "org.springframework.core.io.Resource"); importMapping.put("DateTimeFormat", "org.springframework.format.annotation.DateTimeFormat"); importMapping.put("ApiIgnore", "springfox.documentation.annotations.ApiIgnore"); importMapping.put("ParameterObject", "org.springdoc.api.annotations.ParameterObject"); + if (isUseJSpecify()) { + importMapping.put("Nullable", "org.jspecify.annotations.Nullable"); + } else { + importMapping.put("Nullable", "org.springframework.lang.Nullable"); + } if (isUseSpringBoot3() || isUseSpringBoot4()) { importMapping.put("ParameterObject", "org.springdoc.core.annotations.ParameterObject"); } @@ -1019,10 +1031,39 @@ public void setParameterExampleValue(CodegenParameter p) { } } + /** + * Returns true if the nullableAnnotation.mustache partial would emit {@code @Nullable} + * for this property. + */ + private boolean willEmitNullableAnnotation(CodegenProperty property) { + if (property.required) return false; + if (property.defaultValue == null) { + if (useOptional) return false; + if (isOpenApiNullable()) return !property.isNullable; + return true; + } else { + if (isOpenApiNullable()) return false; + return property.isNullable; + } + } + @Override public void postProcessModelProperty(CodegenModel model, CodegenProperty property) { super.postProcessModelProperty(model, property); + if (isUseJSpecify() && !property.isContainer && willEmitNullableAnnotation(property)) { + String datatype = property.datatypeWithEnum; + int lastDot = datatype.lastIndexOf('.'); + if (lastDot >= 0) { + // Insert annotation between package path and simple class name: a.b.c.@Nullable TypeName + property.vendorExtensions.put("x-jspecify-annotated-type", + datatype.substring(0, lastDot + 1) + "@Nullable " + datatype.substring(lastDot + 1)); + } else { + // No package qualifier – annotation before type is still valid + property.vendorExtensions.put("x-jspecify-annotated-type", "@Nullable " + datatype); + } + } + // add org.springframework.format.annotation.DateTimeFormat when needed if (property.isDate || property.isDateTime) { model.imports.add("DateTimeFormat"); diff --git a/modules/openapi-generator/src/main/resources/JavaSpring/pojo.mustache b/modules/openapi-generator/src/main/resources/JavaSpring/pojo.mustache index 8a93fb054f1f..6aea9b98694a 100644 --- a/modules/openapi-generator/src/main/resources/JavaSpring/pojo.mustache +++ b/modules/openapi-generator/src/main/resources/JavaSpring/pojo.mustache @@ -70,7 +70,7 @@ public {{>sealed}}class {{classname}}{{#parent}} extends {{{parent}}}{{/parent}} private {{>nullableAnnotation}}{{#isNullable}}{{>nullableDataTypeBeanValidation}} {{name}} = JsonNullable.<{{{datatypeWithEnum}}}>undefined();{{/isNullable}}{{^required}}{{^isNullable}}{{>nullableDataTypeBeanValidation}} {{name}}{{#defaultValue}} = {{{.}}}{{/defaultValue}};{{/isNullable}}{{/required}}{{#required}}{{^isNullable}}{{>nullableDataTypeBeanValidation}} {{name}}{{#defaultValue}} = {{{.}}}{{/defaultValue}};{{/isNullable}}{{/required}} {{/openApiNullable}} {{^openApiNullable}} - private {{>nullableAnnotation}}{{>nullableDataType}} {{name}}{{#defaultValue}} = {{{.}}}{{/defaultValue}}; + {{#vendorExtensions.x-jspecify-annotated-type}}private {{{vendorExtensions.x-jspecify-annotated-type}}} {{name}}{{#defaultValue}} = {{{.}}}{{/defaultValue}};{{/vendorExtensions.x-jspecify-annotated-type}}{{^vendorExtensions.x-jspecify-annotated-type}}private {{>nullableAnnotation}}{{>nullableDataType}} {{name}}{{#defaultValue}} = {{{.}}}{{/defaultValue}};{{/vendorExtensions.x-jspecify-annotated-type}} {{/openApiNullable}} {{/isContainer}} {{^isContainer}} @@ -84,7 +84,7 @@ public {{>sealed}}class {{classname}}{{#parent}} extends {{{parent}}}{{/parent}} private {{>nullableAnnotation}}{{#isNullable}}{{>nullableDataTypeBeanValidation}} {{name}} = JsonNullable.<{{{datatypeWithEnum}}}>undefined();{{/isNullable}}{{^required}}{{^isNullable}}{{>nullableDataTypeBeanValidation}} {{name}}{{#useOptional}} = Optional.{{^defaultValue}}empty(){{/defaultValue}}{{#defaultValue}}of({{{.}}}){{/defaultValue}};{{/useOptional}}{{^useOptional}}{{#defaultValue}} = {{{.}}}{{/defaultValue}};{{/useOptional}}{{/isNullable}}{{/required}}{{^isNullable}}{{#required}}{{>nullableDataTypeBeanValidation}} {{name}}{{#defaultValue}} = {{{.}}}{{/defaultValue}};{{/required}}{{/isNullable}} {{/openApiNullable}} {{^openApiNullable}} - private {{>nullableAnnotation}}{{>nullableDataType}} {{name}}{{#isNullable}} = null{{/isNullable}}{{^isNullable}}{{#defaultValue}} = {{{.}}}{{/defaultValue}}{{/isNullable}}; + {{#vendorExtensions.x-jspecify-annotated-type}}private {{{vendorExtensions.x-jspecify-annotated-type}}} {{name}}{{#isNullable}} = null{{/isNullable}}{{^isNullable}}{{#defaultValue}} = {{{.}}}{{/defaultValue}}{{/isNullable}};{{/vendorExtensions.x-jspecify-annotated-type}}{{^vendorExtensions.x-jspecify-annotated-type}}private {{>nullableAnnotation}}{{>nullableDataType}} {{name}}{{#isNullable}} = null{{/isNullable}}{{^isNullable}}{{#defaultValue}} = {{{.}}}{{/defaultValue}}{{/isNullable}};{{/vendorExtensions.x-jspecify-annotated-type}} {{/openApiNullable}} {{/isContainer}} {{/vars}} @@ -144,7 +144,7 @@ public {{>sealed}}class {{classname}}{{#parent}} extends {{{parent}}}{{/parent}} {{^lombok.Data}} {{! begin feature: fluent setter methods }} - public {{classname}} {{name}}({{>nullableAnnotation}}{{{datatypeWithEnum}}} {{name}}) { + public {{classname}} {{name}}({{#vendorExtensions.x-jspecify-annotated-type}}{{{vendorExtensions.x-jspecify-annotated-type}}}{{/vendorExtensions.x-jspecify-annotated-type}}{{^vendorExtensions.x-jspecify-annotated-type}}{{>nullableAnnotation}}{{{datatypeWithEnum}}}{{/vendorExtensions.x-jspecify-annotated-type}} {{name}}) { {{#openApiNullable}} this.{{name}} = {{#isNullable}}JsonNullable.of({{/isNullable}}{{#useOptional}}{{^required}}{{^isNullable}}{{^isContainer}}Optional.of{{#optionalAcceptNullable}}Nullable{{/optionalAcceptNullable}}({{/isContainer}}{{/isNullable}}{{/required}}{{/useOptional}}{{name}}{{#isNullable}}){{/isNullable}}{{#useOptional}}{{^required}}{{^isNullable}}{{^isContainer}}){{/isContainer}}{{/isNullable}}{{/required}}{{/useOptional}}; {{/openApiNullable}} @@ -229,7 +229,7 @@ public {{>sealed}}class {{classname}}{{#parent}} extends {{{parent}}}{{/parent}} {{#deprecated}} @Deprecated {{/deprecated}} -{{#jackson}}{{>jackson_annotations}}{{/jackson}}{{#withXml}}{{>xmlAccessorAnnotation}}{{/withXml}} public {{>nullableAnnotation}}{{>nullableDataTypeBeanValidation}} {{getter}}() { +{{#jackson}}{{>jackson_annotations}}{{/jackson}}{{#withXml}}{{>xmlAccessorAnnotation}}{{/withXml}} public {{#vendorExtensions.x-jspecify-annotated-type}}{{{vendorExtensions.x-jspecify-annotated-type}}}{{/vendorExtensions.x-jspecify-annotated-type}}{{^vendorExtensions.x-jspecify-annotated-type}}{{>nullableAnnotation}}{{>nullableDataTypeBeanValidation}}{{/vendorExtensions.x-jspecify-annotated-type}} {{getter}}() { return {{name}}; } {{/lombok.Getter}} @@ -246,7 +246,7 @@ public {{>sealed}}class {{classname}}{{#parent}} extends {{{parent}}}{{/parent}} {{#deprecated}} @Deprecated {{/deprecated}} -{{#jackson}}{{^vendorExtensions.x-is-jackson-optional-nullable}}{{>jackson_annotations}}{{/vendorExtensions.x-is-jackson-optional-nullable}}{{/jackson}} public void {{setter}}({{>nullableAnnotation}}{{>nullableDataType}} {{name}}) { +{{#jackson}}{{^vendorExtensions.x-is-jackson-optional-nullable}}{{>jackson_annotations}}{{/vendorExtensions.x-is-jackson-optional-nullable}}{{/jackson}} public void {{setter}}({{#vendorExtensions.x-jspecify-annotated-type}}{{{vendorExtensions.x-jspecify-annotated-type}}}{{/vendorExtensions.x-jspecify-annotated-type}}{{^vendorExtensions.x-jspecify-annotated-type}}{{>nullableAnnotation}}{{>nullableDataType}}{{/vendorExtensions.x-jspecify-annotated-type}} {{name}}) { this.{{name}} = {{name}}; } {{/lombok.Setter}} diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java index 032c192fac42..76581e9ef1c6 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java @@ -6637,4 +6637,35 @@ public void shouldNotHaveDocumentationAnnotationWhenUsingLibrarySpringHttpInterf JavaFileAssert.assertThat(Paths.get(outputPath + "/src/main/java/org/openapitools/api/PetApi.java")) .assertMethod("addPet").assertParameter("pet").assertParameterAnnotations().doesNotContainWithName("Parameter"); } + + @Test + public void testIssue23206() throws IOException { + final SpringCodegen codegen = new SpringCodegen(); + + codegen.setLibrary(SPRING_BOOT); + + codegen.schemaMapping().put("SchemaMappedDatatype", "a.b.c.SchemaMappedDatatype"); + + codegen.additionalProperties().put(OPENAPI_NULLABLE, "false"); + codegen.additionalProperties().put(SKIP_DEFAULT_INTERFACE, "true"); + codegen.additionalProperties().put(USE_SPRING_BOOT4, "true"); + codegen.additionalProperties().put(USE_JACKSON_3, "true"); + codegen.additionalProperties().put(USE_TAGS, "true"); + codegen.additionalProperties().put(USE_BEANVALIDATION, "false"); + codegen.additionalProperties().put(USE_JSPECIFY, "true"); + + final Map files = generateFiles(codegen, "src/test/resources/3_0/spring/issue_23206.yaml"); + final var javaFileAssert = JavaFileAssert.assertThat(files.get("SchemaMappedWithTypeUseAnnotationDto.java")); + javaFileAssert + .hasImports("org.jspecify.annotations.Nullable") + .assertProperty("schemaMappedDatatype"); + + javaFileAssert.fileContains("private a.b.c.@Nullable SchemaMappedDatatype schemaMappedDatatype = null;"); + javaFileAssert.fileContains("public a.b.c.@Nullable SchemaMappedDatatype getSchemaMappedDatatype() {"); + javaFileAssert.fileContains("public void setSchemaMappedDatatype(a.b.c.@Nullable SchemaMappedDatatype schemaMappedDatatype) {"); + + javaFileAssert.fileContains("private @Nullable BigDecimal importedDatatype = null;"); + javaFileAssert.fileContains("public @Nullable BigDecimal getImportedDatatype() {"); + javaFileAssert.fileContains("public void setImportedDatatype(@Nullable BigDecimal importedDatatype) {"); + } } diff --git a/modules/openapi-generator/src/test/resources/3_0/spring/issue_23206.yaml b/modules/openapi-generator/src/test/resources/3_0/spring/issue_23206.yaml new file mode 100644 index 000000000000..e98418179743 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/3_0/spring/issue_23206.yaml @@ -0,0 +1,28 @@ +openapi: "3.0.3" +info: + title: Move Annotations in Generated POJOs + description: "Test Placement of Annotations, to allow TYPE_USE Annotations to compile correctly. See #23206" + version: 1.0.0 + +paths: + /some/endpoint: + get: + responses: + "200": + description: OK + +components: + schemas: + SchemaMappedWithTypeUseAnnotationDto: + type: object + properties: + schemaMappedDatatype: + $ref: '#/components/schemas/SchemaMappedDatatype' + importedDatatype: + $ref: '#/components/schemas/ImportedDatatype' + SchemaMappedDatatype: + nullable: true + type: number + ImportedDatatype: + nullable: true + type: number From 68e7f859c0d5582a99ca02a65207134cb0f03380 Mon Sep 17 00:00:00 2001 From: Dominic Fellbaum Date: Sat, 14 Mar 2026 00:16:19 +0100 Subject: [PATCH 2/3] Simplify mustache template Co-authored-by: Christopher Molin <28791817+Chrimle@users.noreply.github.com> --- .../src/main/resources/JavaSpring/pojo.mustache | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/openapi-generator/src/main/resources/JavaSpring/pojo.mustache b/modules/openapi-generator/src/main/resources/JavaSpring/pojo.mustache index 6aea9b98694a..a7a55fa7a25c 100644 --- a/modules/openapi-generator/src/main/resources/JavaSpring/pojo.mustache +++ b/modules/openapi-generator/src/main/resources/JavaSpring/pojo.mustache @@ -70,7 +70,7 @@ public {{>sealed}}class {{classname}}{{#parent}} extends {{{parent}}}{{/parent}} private {{>nullableAnnotation}}{{#isNullable}}{{>nullableDataTypeBeanValidation}} {{name}} = JsonNullable.<{{{datatypeWithEnum}}}>undefined();{{/isNullable}}{{^required}}{{^isNullable}}{{>nullableDataTypeBeanValidation}} {{name}}{{#defaultValue}} = {{{.}}}{{/defaultValue}};{{/isNullable}}{{/required}}{{#required}}{{^isNullable}}{{>nullableDataTypeBeanValidation}} {{name}}{{#defaultValue}} = {{{.}}}{{/defaultValue}};{{/isNullable}}{{/required}} {{/openApiNullable}} {{^openApiNullable}} - {{#vendorExtensions.x-jspecify-annotated-type}}private {{{vendorExtensions.x-jspecify-annotated-type}}} {{name}}{{#defaultValue}} = {{{.}}}{{/defaultValue}};{{/vendorExtensions.x-jspecify-annotated-type}}{{^vendorExtensions.x-jspecify-annotated-type}}private {{>nullableAnnotation}}{{>nullableDataType}} {{name}}{{#defaultValue}} = {{{.}}}{{/defaultValue}};{{/vendorExtensions.x-jspecify-annotated-type}} + private {{#vendorExtensions.x-jspecify-annotated-type}}{{{.}}}{{/vendorExtensions.x-jspecify-annotated-type}}{{^vendorExtensions.x-jspecify-annotated-type}}{{>nullableAnnotation}}{{>nullableDataType}}{{/vendorExtensions.x-jspecify-annotated-type}} {{name}}{{#defaultValue}} = {{{.}}}{{/defaultValue}}; {{/openApiNullable}} {{/isContainer}} {{^isContainer}} From a48a5ae7c2bfb390b5a7d9b106ccd42c70f1f1f9 Mon Sep 17 00:00:00 2001 From: Dominic Fellbaum Date: Sat, 14 Mar 2026 00:45:07 +0100 Subject: [PATCH 3/3] Add support for optional JSpecify dependency in JavaSpring templates - Integrated the `useJSpecify` flag to conditionally include the JSpecify dependency in multiple `pom.mustache` templates. --- .../JavaSpring/libraries/spring-boot/pom-sb3.mustache | 8 ++++++++ .../JavaSpring/libraries/spring-boot/pom.mustache | 8 ++++++++ .../JavaSpring/libraries/spring-cloud/pom-sb3.mustache | 8 ++++++++ .../JavaSpring/libraries/spring-cloud/pom.mustache | 8 ++++++++ .../libraries/spring-http-interface/pom.mustache | 8 ++++++++ 5 files changed, 40 insertions(+) diff --git a/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-boot/pom-sb3.mustache b/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-boot/pom-sb3.mustache index 747c9272cc1a..100e09ddc8f2 100644 --- a/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-boot/pom-sb3.mustache +++ b/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-boot/pom-sb3.mustache @@ -164,6 +164,14 @@ jsr305 3.0.2 + {{#useJSpecify}} + + + org.jspecify + jspecify + 1.0.0 + + {{/useJSpecify}} {{#withXml}} diff --git a/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-boot/pom.mustache b/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-boot/pom.mustache index 38c29f3648a3..f0f3157e64f6 100644 --- a/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-boot/pom.mustache +++ b/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-boot/pom.mustache @@ -194,6 +194,14 @@ jsr305 3.0.2 + {{#useJSpecify}} + + + org.jspecify + jspecify + 1.0.0 + + {{/useJSpecify}} {{#withXml}} diff --git a/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-cloud/pom-sb3.mustache b/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-cloud/pom-sb3.mustache index d62bb06bf8a9..71a3fc2385f2 100644 --- a/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-cloud/pom-sb3.mustache +++ b/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-cloud/pom-sb3.mustache @@ -92,6 +92,14 @@ 3.0.2 {{/parentOverridden}} + {{#useJSpecify}} + + + org.jspecify + jspecify + 1.0.0 + + {{/useJSpecify}} org.springframework.cloud spring-cloud-starter-openfeign diff --git a/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-cloud/pom.mustache b/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-cloud/pom.mustache index 060c2e6ef164..1e018fc6229b 100644 --- a/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-cloud/pom.mustache +++ b/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-cloud/pom.mustache @@ -122,6 +122,14 @@ 3.0.2 {{/parentOverridden}} + {{#useJSpecify}} + + + org.jspecify + jspecify + 1.0.0 + + {{/useJSpecify}} org.springframework.cloud spring-cloud-starter-openfeign diff --git a/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-http-interface/pom.mustache b/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-http-interface/pom.mustache index 7a131774517c..b4a376138037 100644 --- a/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-http-interface/pom.mustache +++ b/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-http-interface/pom.mustache @@ -63,6 +63,14 @@ jsr305 3.0.2 + {{#useJSpecify}} + + + org.jspecify + jspecify + 1.0.0 + + {{/useJSpecify}} jakarta.validation jakarta.validation-api