[java][jaxrs-spec][quarkus] - Add support for OneOfInterfaces & fix JsonTypeName value resolution
Add support for OneOfInterfaces to avoid having circular dependencies because the child schemas components extend a parent class that also has oneOf and mapping pointing to the children.
The bug
x-discriminator-value was only ever populated from a model's Java parentModel. That works for classic allOf inheritance (CatRequest extends PetRequest), but not for the useOneOfInterfaces shape: there the child allOfs a shared base that gets flattened, so the child has no parentModel — it only implements the generated interface, and the discriminator lives on that interface, not on any Java parent.
Result: for oneOf-interface children, x-discriminator-value was never set, and @JsonTypeName fell back to the class name:
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "petType", visible = true)
@JsonSubTypes({
@JsonSubTypes.Type(value = CatRequest.class, name = "CAT"),
@JsonSubTypes.Type(value = DogRequest.class, name = "DOG"),
})
public interface PetRequest { PetType getPetType(); }
// Before — wrong: class name, not the mapping value
@JsonTypeName("CatRequest")
public class CatRequest implements PetRequest { … }
// After — correct: the discriminator mapping value
@JsonTypeName("CAT")
public class CatRequest implements PetRequest { … }
Example:
# -----------------------------------------------
# Base schema in component that contains oneOf and mapping
# Discriminator also lives here on the parent
# Child classes have a circular dependency because allOf to the parent with the oneOf & mapping
# PetRequest (mapping) -> CatRequest (allOf) -> PetRequest
# -----------------------------------------------
PetRequest:
type: object
required:
- petType
- name
properties:
petType:
type: string
enum:
- CAT
- DOG
name:
type: string
discriminator:
propertyName: petType
mapping:
CAT: '#/components/schemas/CatRequest'
DOG: '#/components/schemas/DogRequest'
CatRequest:
type: object
allOf:
- $ref: '#/components/schemas/PetRequest'
- type: object
required:
- breedType
- petType
properties:
breedType:
$ref: '#/components/schemas/CatBreedType'
DogRequest:
type: object
allOf:
- $ref: '#/components/schemas/PetRequest'
- type: object
properties:
breedType:
$ref: '#/components/schemas/DogBreedType'
# -----------------------------------------------
# Base schema a separate component
# Discriminator lives in parent and base object until #24156 is merged
# -----------------------------------------------
PetRequestV2:
type: object
properties:
petType:
$ref: '#/components/schemas/PetType' # --> This will removed once #24156 is merged
oneOf:
- $ref: '#/components/schemas/CatRequestV2'
- $ref: '#/components/schemas/DogRequestV2'
discriminator:
propertyName: petType
mapping:
CAT: '#/components/schemas/CatRequestV2'
DOG: '#/components/schemas/DogRequestV2'
PetRequestV2Base:
type: object
required:
- petType
- name
properties:
petType:
$ref: '#/components/schemas/PetType'
name:
type: string
CatRequestV2:
type: object
allOf:
- $ref: '#/components/schemas/PetRequestV2Base'
- type: object
properties:
breedType:
$ref: '#/components/schemas/CatBreedType'
DogRequestV2:
type: object
allOf:
- $ref: '#/components/schemas/PetRequestV2Base'
- type: object
properties:
breedType:
$ref: '#/components/schemas/DogBreedType'
PR checklist
- Read the contribution guidelines.
- Run the following to build the project and update samples:
(For Windows users, please run the script in WSL)./mvnw clean package || exit ./bin/generate-samples.sh ./bin/configs/*.yaml || exit ./bin/utils/export_docs_generators.sh || exit
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 useOneOfInterfaces to jaxrs-spec, generating oneOf schemas as Java interfaces with a typed discriminator getter, and fixes subtype mapping so @JsonTypeName uses the discriminator mapping value. Opt-in; default output is unchanged.
-
New Features
- Route
x-is-one-of-interfacemodels inmodel.mustachetooneof_interface.mustacheto emit a plain interface with Jackson type info and a typed getter (enum when applicable); supportsadditionalOneOfTypeAnnotations.mustacheand optionalJsonTypeInfo.DEDUCTION. - Add sample
samples/server/petstore/jaxrs-spec-oneof-interface, configbin/configs/jaxrs-spec-oneof-interface.yaml, tests, and register the sample in the JAX-RS samples workflow.
- Route
-
Bug Fixes
- In
JavaJAXRSSpecServerCodegen, index discriminators for generated oneOf interfaces and resolve subtype mappings from eitherparentModelor the implemented interface viax-implements, settingx-discriminator-valuefor correct@JsonTypeNameand Jackson polymorphic (de)serialization.
- In