Skip to content

[java] honor useJspecify in restclient/webclient ApiClient support class#24055

Merged
wing328 merged 1 commit into
OpenAPITools:masterfrom
austek:fix/java-client-apiclient-jspecify-import
Jun 22, 2026
Merged

[java] honor useJspecify in restclient/webclient ApiClient support class#24055
wing328 merged 1 commit into
OpenAPITools:masterfrom
austek:fix/java-client-apiclient-jspecify-import

Conversation

@austek

@austek austek commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

PR: [java] honor useJspecify in restclient/webclient ApiClient support class

PR checklist

  • Read the contribution guidelines.
  • Pull Request title clearly describes the work and is named according to our commit naming conventions.
  • File the PR against the correct branch: master (no breaking changes).
  • Run the shell script ./bin/generate-samples.sh to update all Petstore samples related to your fix. Regenerated the affected samples and committed the changes.
  • If your PR is targeting a particular programming language and you want a community member to review it, find them in the list of technical committee members and @ mention them.

cc Java technical committee: @bbdouglas @sdltj @martin-mfg @welshm @Bridgevine — and @jpfinne (author of useJspecify, #23256).

Description

Fixes #24054.

useJspecify=true converts model/API nullness to org.jspecify.annotations.Nullable, but the
restclient and webclient ApiClient support classes still hardcoded
import {{javaxPackage}}.annotation.Nullable;. That left every generated client mixing JSpecify
everywhere except the ApiClient, which kept jakarta.annotation.Nullable (or javax.*),
breaking "JSpecify-only" enforcement (ArchUnit / NullAway).

@Nullable is referenced as a simple name in both templates (createDefaultMapper(@Nullable DateFormat dateFormat)), so only the import line needs to be made conditional. No usage sites
change; behavior with useJspecify=false is unchanged. The other java-library ApiClient
templates do not import Nullable and are unaffected.

Diff

--- a/modules/openapi-generator/src/main/resources/Java/libraries/restclient/ApiClient.mustache
+++ b/modules/openapi-generator/src/main/resources/Java/libraries/restclient/ApiClient.mustache
@@ -79,7 +79,12 @@
 import java.util.TimeZone;
 import java.util.function.Supplier;
 
-import {{javaxPackage}}.annotation.Nullable;
+{{#useJspecify}}
+import org.jspecify.annotations.Nullable;
+{{/useJspecify}}
+{{^useJspecify}}
+import {{javaxPackage}}.annotation.Nullable;
+{{/useJspecify}}
 
 {{#jsr310}}
--- a/modules/openapi-generator/src/main/resources/Java/libraries/webclient/ApiClient.mustache
+++ b/modules/openapi-generator/src/main/resources/Java/libraries/webclient/ApiClient.mustache
@@ -82,7 +82,12 @@
 import java.util.Map.Entry;
 import java.util.TimeZone;
 
-import {{javaxPackage}}.annotation.Nullable;
+{{#useJspecify}}
+import org.jspecify.annotations.Nullable;
+{{/useJspecify}}
+{{^useJspecify}}
+import {{javaxPackage}}.annotation.Nullable;
+{{/useJspecify}}
 
 {{#jsr310}}

How to verify

./bin/generate-samples.sh bin/configs/java-restclient-*.yaml
./bin/generate-samples.sh bin/configs/java-webclient-*.yaml

Generate with useJspecify=true and confirm ApiClient.java imports
org.jspecify.annotations.Nullable; generate with useJspecify=false and confirm it still
imports {{javaxPackage}}.annotation.Nullable (jakarta or javax per useJakartaEe).

Notes

  • Run ./bin/generate-samples.sh + ./bin/utils/export_docs_generators.sh before pushing so the
    committed Petstore samples for any useJspecify restclient/webclient config are regenerated;
    CI fails if samples are stale.
  • Commit message (their Conventional-ish convention): [java] honor useJspecify in restclient/webclient ApiClient.

Summary by cubic

Honor useJspecify in Java restclient and webclient ApiClient templates by making the @Nullable import conditional: org.jspecify.annotations.Nullable when useJspecify=true, otherwise {{javaxPackage}}.annotation.Nullable.
This removes mixed nullness annotations in generated clients and keeps behavior unchanged when JSpecify is off.

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

Review in cubic

The restclient and webclient ApiClient support classes hardcoded
'import {javaxPackage}.annotation.Nullable;' regardless of useJspecify, so
generated clients used org.jspecify everywhere except ApiClient, which kept
jakarta/javax. Guard the import on useJspecify; @nullable is used as a simple
name so only the import changes. Regenerated the two affected jspecify samples.

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No issues found across 4 files

Re-trigger cubic

@wing328 wing328 added this to the 7.24.0 milestone Jun 22, 2026
@wing328 wing328 merged commit 4a5f3a7 into OpenAPITools:master Jun 22, 2026
108 checks passed
@wing328

wing328 commented Jun 22, 2026

Copy link
Copy Markdown
Member

thanks for the fix, which has been merged

@austek austek deleted the fix/java-client-apiclient-jspecify-import branch June 22, 2026 12:41
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.

[BUG][JAVA] useJspecify=true: java/restclient and java/webclient ApiClient support class still imports jakarta.annotation.Nullable

2 participants