Bug Report Checklist
Description
When useJspecify is enabled, the generator correctly adds @NullMarked at the package level and applies @Nullable to fields, getter return types, and regular setter parameters for optional properties. However, the fluent setter parameters do not get @Nullable applied, creating an inconsistent nullness contract.
For example, given an optional firstName property, the generated code is:
// Field - correct
private @Nullable String firstName;
// Getter - correct
public @Nullable String getFirstName() { ... }
// Setter - correct
public void setFirstName(@Nullable String firstName) { ... }
// Fluent setter - INCORRECT (missing @Nullable on parameter)
public UserBase firstName(String firstName) { ... }
Under @NullMarked, the fluent setter parameter is effectively @nonnull, which means static analysis tools (e.g. NullAway, IntelliJ inspections) will flag passing null to the fluent setter as an error — even though the underlying field is nullable and the property is optional in the OpenAPI spec.
openapi-generator version
v7.22.0
OpenAPI declaration file content or url
openapi: 3.1.1
info:
title: Example API
version: 0.0.1
paths: {}
components:
schemas:
UserBase:
type: object
description: A base object for user details.
properties:
firstName:
description: The user's first name.
type: string
minLength: 1
maxLength: 32
example: John
lastName:
description: The user's last name.
type: string
minLength: 1
maxLength: 32
example: Doe
email:
type: string
format: email
maxLength: 128
example: john.doe@example.com
Generation Details
<generatorName>spring</generatorName>
<configOptions>
<!-- Packages -->
<apiPackage>...</apiPackage>
<modelPackage>...</modelPackage>
<invokerPackage>...</invokerPackage>
<useSpringBoot4>true</useSpringBoot4>
<useJspecify>true</useJspecify>
<interfaceOnly>true</interfaceOnly>
<hateoas>true</hateoas>
<dateLibrary>java8</dateLibrary>
<returnResponseEntity>true</returnResponseEntity>
<useTags>true</useTags>
<skipDefaultInterface>true</skipDefaultInterface>
<useBeanValidation>true</useBeanValidation>
<hideGenerationTimestamp>true</hideGenerationTimestamp>
</configOptions>
Steps to reproduce
- Create an OpenAPI spec with optional properties (properties not listed in required)
- Generate with
useJspecify: true using the spring generator
- Observe that the generated
package-info.java contains @NullMarked
- Observe that fields are annotated
@Nullable, getters return @Nullable, and regular setters accept @Nullable
- Observe that fluent setters (e.g.
public UserBase firstName(String firstName)) do not have @Nullable on the parameter
- Static analysis tools now report an error when passing null to the fluent setter
Actual output:
public UserBase firstName(String firstName) {
this.firstName = firstName;
return this;
}
Expected output:
public UserBase firstName(@Nullable String firstName) {
this.firstName = firstName;
return this;
}
Related issues/PRs
[java] [Spring] useJspecify for java clients and spring generator #23256
I can see the same issue happening in the server Foo class: https://github.com/OpenAPITools/openapi-generator/pull/23256/changes#diff-bc8ecb319983dd05e330050f16efc8465757a345be5e825ee559b943dfc11ca7
But not in the client Foo class: https://github.com/OpenAPITools/openapi-generator/pull/23256/changes#diff-f27dea557f26c8d1143994612fc1c88f19b52f7373b8169925be312634107846
Bug Report Checklist
Description
When
useJspecifyis enabled, the generator correctly adds@NullMarkedat the package level and applies@Nullableto fields, getter return types, and regular setter parameters for optional properties. However, the fluent setter parameters do not get@Nullableapplied, creating an inconsistent nullness contract.For example, given an optional
firstNameproperty, the generated code is:Under @NullMarked, the fluent setter parameter is effectively @nonnull, which means static analysis tools (e.g. NullAway, IntelliJ inspections) will flag passing null to the fluent setter as an error — even though the underlying field is nullable and the property is optional in the OpenAPI spec.
openapi-generator version
v7.22.0
OpenAPI declaration file content or url
Generation Details
Steps to reproduce
useJspecify: trueusing the spring generatorpackage-info.javacontains@NullMarked@Nullable, getters return@Nullable, and regular setters accept@Nullablepublic UserBase firstName(String firstName)) do not have@Nullableon the parameterActual output:
Expected output:
Related issues/PRs
[java] [Spring] useJspecify for java clients and spring generator #23256
I can see the same issue happening in the server Foo class: https://github.com/OpenAPITools/openapi-generator/pull/23256/changes#diff-bc8ecb319983dd05e330050f16efc8465757a345be5e825ee559b943dfc11ca7
But not in the client Foo class: https://github.com/OpenAPITools/openapi-generator/pull/23256/changes#diff-f27dea557f26c8d1143994612fc1c88f19b52f7373b8169925be312634107846