Skip to content

[BUG][JAVA] parent class declares a field from subclasses causing a name clash #23527

@winklerm

Description

@winklerm

Bug Report Checklist

  • Have you provided a full/minimal spec to reproduce the issue?
  • Have you validated the input using an OpenAPI validator?
  • Have you tested with the latest master to confirm the issue still exists?
  • Have you searched for related issues/PRs?
  • What's the actual output vs expected output?
  • [Optional] Sponsorship to speed up the bug fix or feature request (example)
Description

The problem can be observed when trying to generate java client code for GeoJSON specification, let's see a simplified case:

  • parent GeoJsonObject containing only type property also used in the discriminator and oneOf,
  • child schemas:
    • Polygon containing coordinates property of type array of double,
    • MultiPolygon containing coordinates property of type array of arrays of double.

The generated GeoJsonObject parent class contains unexpectedly also the coordinates field with one of the above types, but the type cannot be overriden by one of the subclasses leading to compilation errors such as:

name clash: coordinates(List<Double>) in Polygon and coordinates(List<List<Double>>) in GeoJsonGeometry have the same erasure, yet neither overrides the other

I would expect the generated GeoJsonObject class not to contain any fields (coordinates in this case) which do not have the same type in the subclasses (alternatively, it could have a more generic type, but it is hard to say how that could be useful for different use-cases).

Happens to me with generator java and most libraries, the only two libraries which worked for me were okhttp-gson and jersey3, but our users would like to use apache-httpclient.

openapi-generator version

The problem can be reproduced with the latest main, noticed in 7.21.0.

OpenAPI declaration file content or url
openapi: 3.0.3
info:
  title: GeoJSON Discriminator Test
  version: 1.0.0
paths: {}
components:
  schemas:
    GeoJsonObject:
      type: object
      properties:
        type:
          type: string
      required:
        - type
      discriminator:
        propertyName: type
      oneOf:
        - $ref: '#/components/schemas/Polygon'
        - $ref: '#/components/schemas/MultiPolygon'
    Polygon:
      allOf:
        - $ref: '#/components/schemas/GeoJsonObject'
        - type: object
          properties:
            coordinates:
              type: array
              items:
                type: number
                format: double
    MultiPolygon:
      allOf:
        - $ref: '#/components/schemas/GeoJsonObject'
        - type: object
          properties:
            coordinates:
              type: array
              items:
                type: array
                items:
                  type: number
                  format: double
Generation Details
docker run --rm -v "${PWD}:/local" openapitools/openapi-generator-cli generate \
-i /local/geojson_discriminator.yaml \
-g java \
--library apache-httpclient -o /local/test
Steps to reproduce

Please see the test added in the linked PR.

Suggest a fix

Please see the linked PR for a fix which works for our use-case, but I believe it cannot be applied as is to keep backward compatibility. It also breaks two tests:

[ERROR] org.openapitools.codegen.java.spring.SpringCodegenTest.allOfDuplicatedProperties -- Time elapsed: 0.044 s <<< FAILURE!
java.lang.AssertionError: No constructor with parameter(s) [String, Integer, Integer, String, String]
        at org.openapitools.codegen.java.assertions.JavaFileAssert.assertConstructor(JavaFileAssert.java:147)
        at org.openapitools.codegen.java.spring.SpringCodegenTest.allOfDuplicatedProperties(SpringCodegenTest.java:5182)
...
[ERROR] org.openapitools.codegen.ruby.RubyClientCodegenTest.allOfDuplicatedPropertiesTest -- Time elapsed: 0.002 s <<< FAILURE!
java.lang.AssertionError: expected [5] but found [3]
...

Perhaps a new configuration property could be introduced to disallow pulling up type-incompatible properties into the common parent? Or is there a more systemic solution?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions