[BUG][java][jersey2] Generated java jersey2 client fails compilation when 'allOf' child has enum constraint
Created by: sebastien-rosset
Bug Report Checklist
-
Have you provided a full/minimal spec to reproduce the issue? -
Have you validated the input using an OpenAPI validator (example)? -
What's the version of OpenAPI Generator used? -
Have you search for related issues/PRs? -
What's the actual output vs expected output? -
[Optional] Bounty to sponsor the fix (example)
Description
The generated Java client code with the jersey2 library fails compilation when:
- A Animal schema is defined with a property P1 of type "string".
- A Cat child schema is defined with 'allOf' Animal.
- The P1 property is redefined in the Cat child class.
- A enum constraint is added to property P1 in the child class.
The same problem is likely to occur with 'oneOf' and 'anyOf', though I have not tested these particular scenarios.
openapi-generator version
openapi master branch as of August 19th 2020
OpenAPI declaration file content or url
Here is a minimal OpenAPI doc to reproduce the problem. The full OpenAPI doc is available in PR #7251 at https://github.com/OpenAPITools/openapi-generator/pull/7251/files#diff-aa56ad872f3213179c27da9d73dec49aR2090
Animal:
type: object
properties:
# Define a pet_type property of type "string" with no enum constraint.
# It's just a plain string with no enum constraint.
pet_type:
type: string
Cat:
allOf:
- $ref: '#/components/schemas/Animal'
- type: object
properties:
pet_type:
# Add a 'enum' constraint to the pet_type property and a 'default' value.
# This is useful because it specifies there is only one possible value for this schema.
# The code generator should be able to leverage this piece of information to generate
# a Java class constructor where the 'pet_type' property is initialized to 'Cat' by default.
# Without the enum constraint, there is no way for the code generator to determine
# what are the possible values of 'pet_type'.
# Without the enum, the developer creating a 'Cat' object using Java would be forced
# to explicitly set the value of 'pet_type'. That would be both surprising and tedious
# because humans know there is only one possible value.
enum:
- Cat
default: Cat
Generation Details
Steps to reproduce
- Checkout branch from PR #7215.
- Type
bin/generate-samples.sh bin/configs/java-jersey2-8.yaml
Related issues/PRs
I have raised PR #7251 to show how the generated code is failing.
Suggest a fix
First, let's look at the problems:
- A field with the same name is redefined in Java sub-classes.
- Getters and Setters methods are overridden in the Java sub-classes but with a different signature
- There is no
@Override
annotation in the generated code. - More generally the code generator is not aware that methods are overridden in sub-classes.
The code for the parent and child class is generated as shown below.
public class Animal {
public String getPetType() {
return petType;
}
public class Cat extends Animal {
// Overrides getPetType from super class, but the return value is not compatible.
public PetTypeEnum getPetType() {
return petType;
}
This causes the following compilation error:
Compilation failure
[ERROR] error: getPetType() in Cat cannot override getPetType() in Animal
[ERROR] return type PetTypeEnum is not compatible with String
Proposed changes:
- Detect when property is redefined in 'allOf'/'oneOf'/'anyOf' child.
- Detect which generated methods are overridden in java subclasses, e.g.
getPetType
is overridden. Ensure the generated methods have the same signature. - Do not redefine field in sub-class. Java fields cannot be overridden in a subclass. If a field is redefined in a subclass with the same name as a field in the superclass, the field in the subclass will hide (shadow) the field in the superclass. If the subclass tries to access the field, it will access the field in the subclass. However, if the subclass calls up into a method in the superclass, and that method accesses the field with the same name as in the subclass, it is the field in the superclass that is accessed.