[Java][jaxrs-spec] - Add JSpecify support

Merged
IG
1mo ago
+1708-11

Adds useJspecify support to the jaxrs-spec generator.

Fixes #24886

Background

jaxrs-spec had no jspecify support at all — this is not a case of one library missing from an existing feature. There was no useJspecify option, no applyJspecify() wiring, and the generator emitted no nullability annotations for any library.

Support is added generator-wide rather than per-library, because pojo.mustache and the parameter partials are shared by all six libraries (default, quarkus, thorntail, openliberty, helidon, kumuluzee); only quarkus overrides formParams. All six were verified to produce the annotations.

Changes

  • JavaJAXRSSpecServerCodegen: the useJspecify cliOption, the applyJspecify() call and override, and the Nullable import for models (fromModel) and operations (fromOperation).
  • Shared pojo.mustache — field, getter, setter and fluent setter — and the six parameter partials, plus the quarkus formParams override.
  • New JavaJaxRS/spec copies of modelPackageInfo/apiPackageInfo and the nullable* partials. Unlike the java client libraries, which all resolve against one shared Java template dir, jaxrs-spec has its own directory with no fallback, so these could not simply be inherited.
  • The base pom.mustache swaps com.google.code.findbugs:jsr305 for org.jspecify:jspecify under the flag, matching how native/resttemplate/etc. already handle it; the quarkus pom gains the jspecify dependency.
  • Regenerated docs/generators/jaxrs-spec.md.

Two things worth calling out for review:

Ordering. applyJspecify() has to run after the supportingFiles.clear() in processOpts(), which would otherwise drop the @NullMarked package-info files it registers.

jaxrs-cxf-cdi. It extends this generator but sets its own cxf-cdi template directory, so it inherited the option while producing no annotations at all — the exact "advertised but does nothing" defect this work fixes elsewhere. It now calls removeOption(USE_JSPECIFY), alongside the existing removeOption(GENERATE_JSON_CREATOR).

Testing

  • Two new tests in JavaJAXRSSpecServerCodegenTest: one asserting the annotations, type-use placement on a qualified type (java.math.@Nullable BigDecimal), that required properties are not annotated, both package-info files and the JAX-RS parameters; one asserting that with the flag off nothing is emitted and the pom still carries jsr305. Both fail if the template wiring is reverted.
  • JavaJAXRSSpecServerCodegenTest: 155 tests green.
  • New sample samples/server/petstore/jaxrs-spec-quarkus-jspecify, registered in samples-jdk17.yaml (the quarkus library targets Java 17 under useJakartaEe). It compiles with mvn compile.
  • Flag-off output is byte-identical to the parent branch for both the default and quarkus libraries, verified by diffing against a jar built without these changes.
  • ./bin/generate-samples.sh ./bin/configs/*.yaml — 803 generators, no diff in any existing sample.

PR checklist

  • Read the contribution guidelines.
  • 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
    
    (For Windows users, please run the script in WSL)
    Commit all changed files.
    This is important, as CI jobs will verify all generator outputs of your HEAD commit as it would merge with master.
    These must match the expectations made by your contribution.
    You may regenerate an individual generator by passing the relevant config(s) as an argument to the script, for example ./bin/generate-samples.sh bin/configs/java*.
    IMPORTANT: Do NOT purge/delete any folders/files (e.g. tests) when regenerating the samples as manually written tests may be removed.
  • If your PR is targeting a particular programming language, @mention the technical committee members, so they are more likely to review the pull request.

Summary by cubic

Adds useJspecify support to the jaxrs-spec generator and the java microprofile client library. Generated output can now include @NullMarked package-info files and @Nullable annotations on optional properties and parameters.

  • The shared jaxrs-spec model and parameter templates cover all six libraries; only quarkus has its own formParams override.
  • jaxrs-cxf-cdi removes the option because it uses its own template directory and would otherwise advertise support it doesn't provide.
  • microprofile advertised useJspecify in its docs but rejected it; it now works, including on enum getters and optional file form params.
  • With the flag on, generated poms use org.jspecify:jspecify instead of jsr305; with the flag off, output is unchanged.
  • Adds tests covering the annotations, type-use placement on qualified types, and useJspecify combined with useSealedOneOfInterfaces.
  • Adds jaxrs-spec-quarkus-jspecify and microprofile-rest-client-3.0-jspecify samples.