[Java][jaxrs-spec] Annotate nullable @JsonCreator/@JsonbCreator parameters with JSpecify (fixes #25438)

Merged
IV
2d ago
+46-6

Fixes #25438. Follow-up to #24885.

Problem

With useJspecify=true, jaxrs-spec annotates fields, getters, setters and fluent setters of nullable properties
with @Nullable, but not the parameters of the generated @JsonCreator constructor (nor, since #25177, the
@JsonbCreator constructor). These constructors take the required properties, so a property that is both
required and nullable: true ends up with an unannotated parameter. Because the model package is @NullMarked, that
parameter means non-null, and calling the constructor with null is reported as an error by NullAway (JSpecify mode)
and other JSpecify-aware checkers, although the spec explicitly allows null.

Example from the existing jaxrs-spec-quarkus-jspecify sample (RequiredAndNullable), before:

private @Nullable String str;
...
@JsonCreator
public RequiredAndNullable(
  @JsonProperty(required = true, value = "str") String str,   // non-null under @NullMarked

after:

  @JsonProperty(required = true, value = "str") @Nullable String str,

The Spring and Java client generators already got the equivalent fix in #24563 and #24711; jaxrs-spec has its own
template directory and doesn't inherit it.

Changes

  • JavaJaxRS/spec/pojo.mustache: the @JsonCreator and @JsonbCreator constructor parameters use the same
    pattern as the getter: nullable_var_annotations stashes the annotation and the jSpecifyDatatype lambda emits it,
    so qualified types keep type-use placement (java.math.@Nullable BigDecimal). Both changes are guarded by
    {{#useJspecify}}/the lambda, so output without useJspecify is unchanged.
  • JavaJAXRSSpecServerCodegenTest: testUseJspecify now asserts the @JsonCreator parameters of
    RequiredAndNullable (nullable ones annotated, onlyRequired not); new testUseJspecifyWithJsonbCreator asserts
    the same for the JSON-B constructor.
  • Updated sample jaxrs-spec-quarkus-jspecify (RequiredAndNullable.java). No other sample uses useJspecify with
    jaxrs-spec, so no other sample changes.

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/jaxrs-spec-quarkus-jspecify.yaml || exit
    
    No generator option changed, so export_docs_generators.sh produces no diff.
  • @mention the technical committee members for Java.

cc @bbdouglas @sreeshas @jfiala @lukoyanov @cbornet @jeff9finger @karismann @Zomzog @lwlee2608 @martin-mfg @KannaKim