openapi-generator icon indicating copy to clipboard operation
openapi-generator copied to clipboard

[java] Compilation failure when 'discriminator' is introduced

Open yuanpli opened this issue 6 years ago • 16 comments

Description

I got the following error when generate code by using openapi-generator-maven-plugin.

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:compile (default-compile) on project swagger-vnfm: Compilation failure
[ERROR] /swagger-vnfm/target/generated-sources/src/main/java/com/openapi/test/VimConnectionInfo.java:[43,49] incompatible types: java.lang.String cannot be converted to com.openapi.test.VimType
openapi-generator version

3.2.0

OpenAPI declaration file content or url
swagger: '2.0'
info:
  description: This spec is mainly for testing
  version: 1.0.0
  title: Swagger Petstore
  termsOfService: 'http://swagger.io/terms/'
  contact:
    email: [email protected]
  license:
    name: Apache-2.0
    url: 'http://www.apache.org/licenses/LICENSE-2.0.html'
host: 'petstore.swagger.io:80'
basePath: /v2
paths:
  /test:
    get:
      description: Gets all operation occurrence resources.
      responses:
        '200':
          description: Successful response
          schema:
            type: string
        default:
          description: Error payload
          schema:
            type: string
      tags:
        - test
schemes:
  - http
definitions:
  VimType:
    description: Type of the VIM info structure.
    type: string
    enum:
      - OPENSTACK_V2
      - OPENSTACK_V3
      - VMWARE_VCLOUD
      - OTHER_VIM_INFO
  VimConnectionInfo:
    type: object
    required:
      - id
      - vimType
    discriminator: vimType
    properties:
      id:
        description: Identifier of the VIM
        type: string
      vimType:
        $ref: '#/definitions/VimType'
externalDocs:
  description: Find out more about Swagger
  url: 'http://swagger.io'
Command line used for generation

mvn clean compile

Steps to reproduce

The maven pom.xml is

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.vnfm.model</groupId>
    <artifactId>swagger-vnfm</artifactId>
    <packaging>jar</packaging>
    <version>DYNAMIC-SNAPSHOT</version>
    <name>swagger-vnfm</name>
    <url>http://maven.apache.org</url>
    <dependencies>
        <dependency>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-annotations</artifactId>
            <version>${swagger-core-version}</version>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>${gson-version}</version>
        </dependency>
    </dependencies>
    <properties>
        <java.version>1.8</java.version>
        <maven.compiler.source>${java.version}</maven.compiler.source>
        <maven.compiler.target>${java.version}</maven.compiler.target>
        <swagger-core-version>1.5.21</swagger-core-version>
        <gson-version>2.8.1</gson-version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <build>
        <plugins>
            <plugin>
                <groupId>org.openapitools</groupId>
                <artifactId>openapi-generator-maven-plugin</artifactId>
                <version>3.2.0</version>
                <executions>
                    <execution>
                        <id>lcm-generate</id>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                        <configuration>
                            <inputSpec>${project.basedir}/src/main/resources/swagger.yaml</inputSpec>
                            <language>java</language>
                            <generateApis>false</generateApis>
                            <generateModelTests>false</generateModelTests>
                            <generateModelDocumentation>false</generateModelDocumentation>
                            <generateSupportingFiles>false</generateSupportingFiles>
                            <skipOverwrite>true</skipOverwrite>
                            <configOptions>
                                <dateLibrary>java8</dateLibrary>
                            </configOptions>
                            <output>${project.build.directory}/generated-sources</output>
                            <modelPackage>com.openapi.test</modelPackage>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

Related issues/PRs

No

Suggest a fix/enhancement

yuanpli avatar Aug 14 '18 06:08 yuanpli

Thank you for this feedback. It is very valuable.

I think the specific issue is that your discriminator is an enum. This might be not supported yet.

Other question from my side: Is your spec complete? What is the idea behind using a discriminator here? There is no mapping and no ComposedSchema (oneOf, allOf).

jmini avatar Aug 14 '18 08:08 jmini

Hi,

This swagger is provided by collaborator, and what I used here is simplified for the privacy policy. The whole definition for object VimConnectionInfo is posted as below. And there is a explanation for why used discriminator "Type of the VIM info structure. This field will be used as a discriminator for different types of VIMs. OTHER_VIM_INFO is provided for forward compatibility with later microversions of the API."

    "VimConnectionInfo": {
      "type": "object", 
      "required": [
        "id", 
        "vimType"
      ], 
      "discriminator": "vimType", 
      "properties": {
        "id": {
          "description": "Identifier of the VIM", 
          "$ref": "#/definitions/Identifier"
        }, 
        "vimType": {
          "description": "Type of the VIM info structure. This field will be used as a discriminator for different types of VIMs. `OTHER_VIM_INFO` is provided for forward compatibility with later microversions of the API.", 
          "type": "string", 
          "enum": [
            "OPENSTACK_V2", 
            "OPENSTACK_V3", 
            "VMWARE_VCLOUD", 
            "OTHER_VIM_INFO"
          ]
        }
      }, 
      "description": "This is a base type that has derivatives. In all places where it is referenced the following types should be expected: ['OPENSTACK_V2', 'OPENSTACK_V3', 'VMWARE_VCLOUD', 'OTHER_VIM_INFO']. The actual type is determined by the field 'vimType' which contains the type name.", 
      "example": {
        "id": "global_identifier_9cd6192c-899c-11e8", 
        "vimType": "OPENSTACK_V2", 
        "interfaceInfo": {
          "endpoint": "https://example.com/url"
        }, 
        "accessInfo": {
          "username": "string", 
          "password": "password", 
          "region": "string", 
          "tenant": "string"
        }
      }
    }

yuanpli avatar Aug 14 '18 08:08 yuanpli

Any update?

yuanpli avatar Aug 17 '18 01:08 yuanpli

Feel free to propose a pull request

jmini avatar Aug 17 '18 06:08 jmini

This issue appears to be fixed in 4.1.3.

keenanpepper avatar Oct 18 '19 23:10 keenanpepper

Using an enum descriminator is still broken on 4.2.3 and the current master (4.3.0-SNAPSHOT).

I built a simple example based on the OpenAPI docs:

components:
  schemas:
    Pet:
      oneOf:
        - $ref: "#/components/schemas/Cat"
        - $ref: "#/components/schemas/Dog"
        - $ref: "#/components/schemas/Lizard"
      discriminator:
        propertyName: petType
        mapping:
          Cat: "#/components/schemas/Cat"
          Dog: "#/components/schemas/Dog"
          Lizard: "#/components/schemas/Lizard"

    Cat:
      type: object
      properties:
        petType:
          $ref: "#/components/schemas/PetType"
        name:
          type: string

    Dog:
      type: object
      properties:
        petType:
          $ref: "#/components/schemas/PetType"
        bark:
          type: string

    Lizard:
      type: object
      properties:
        petType:
          $ref: "#/components/schemas/PetType"
        lovesRocks:
          type: boolean

    PetType:
      type: string
      enum:
        - Cat
        - Dog
        - Lizard

Generated with

java -jar openapi-generator-cli.jar generate \
  -i api.yaml \
  --api-package 'com.test.api' \
  --model-package 'com.test.model' \
  -g java \
  --library 'retrofit2' \
  -o generated/

The issue seems to be this line in the constructor of the base type (Pet):

this.petType = this.getClass().getSimpleName();

which doesn't compile unless petType is a String. The fix should be rather simple. Whenever the discriminator is an enum, the constructor should be something like this:

this.petType = PetType.fromValue(this.getClass().getSimpleName());

antweb avatar Feb 04 '20 10:02 antweb

Any update on this?

mukhiparshant avatar Jun 09 '21 15:06 mukhiparshant

It appears this is still an issue if we have a discriminator but only one available option:

      "submitSelfServiceRecoveryFlowBody": {
        "discriminator": {
          "mapping": {
            "link": "#/components/schemas/submitSelfServiceRecoveryFlowWithLinkMethodBody"
          },
          "propertyName": "method"
        },
        "oneOf": [
          {
            "$ref": "#/components/schemas/submitSelfServiceRecoveryFlowWithLinkMethodBody"
          }
        ]
      },

Will cause:

[ERROR] /sdk/clients/client/java/src/main/java/sh/ory/model/SubmitSelfServiceRecoveryFlowBody.java:[91,47] error: incompatible types: String cannot be converted to MethodEnum

This works:

      "submitSelfServiceRecoveryFlowBody": {
        "discriminator": {
          "mapping": {
            "link": "#/components/schemas/submitSelfServiceRecoveryFlowWithLinkMethodBody",
            "foo": "#/components/schemas/something-else"
          },
          "propertyName": "method"
        },
        "oneOf": [
          {
            "$ref": "#/components/schemas/submitSelfServiceRecoveryFlowWithLinkMethodBody"
          },
          {
            "$ref": "#/components/schemas/something-else"
          }
        ]
      },

aeneasr avatar Sep 04 '21 08:09 aeneasr

exact same issue with 5.2.1 today. I can't change the spec file, as it's provided by a vendor. Not sure what my options are....

EDIT:

I switched to https://github.com/swagger-api/swagger-codegen/tree/master/modules/swagger-codegen-maven-plugin and used <version>3.0.29</version> and my models are generated successfully

<plugin>
                <groupId>io.swagger.codegen.v3</groupId>
                <artifactId>swagger-codegen-maven-plugin</artifactId>
                <version>3.0.29</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                        <configuration>
                            <inputSpec>${project.basedir}/src/main/resources/petstore.json</inputSpec>
                            <language>java</language>
                            <modelPackage>com.my-comp.some-vendor-we-use.models</modelPackage>
                            <withXml>true</withXml>
                            <generateApis>false</generateApis>
                            <generateModels>true</generateModels>
                            <generateModelTests>false</generateModelTests>
                            <generateModelDocumentation>true</generateModelDocumentation>
                            <generateSupportingFiles>false</generateSupportingFiles>
                            <ignoreFileOverride>${project.basedir}/.swagger-codegen-ignore</ignoreFileOverride>
                            <configOptions>
                                <sourceFolder>src/java/main</sourceFolder>
                                <bigDecimalAsString>true</bigDecimalAsString>
                                <dateLibrary>java8</dateLibrary>
<!--
library
	    library template (sub-template) to use (Default: okhttp-gson)
	        jersey1 - HTTP client: Jersey client 1.19.4. JSON processing: Jackson 2.10.1. Enable gzip request encoding using '-DuseGzipFeature=true'.
	        feign - HTTP client: OpenFeign 9.4.0. JSON processing: Jackson 2.10.1
	        jersey2 - HTTP client: Jersey client 2.26. JSON processing: Jackson 2.10.1
	        okhttp-gson - HTTP client: OkHttp 2.7.5. JSON processing: Gson 2.8.1. Enable Parcelable models on Android using '-DparcelableModel=true'. Enable gzip request encoding using '-DuseGzipFeature=true'.
	        retrofit - HTTP client: OkHttp 2.7.5. JSON processing: Gson 2.3.1 (Retrofit 1.9.0). IMPORTANT NOTE: retrofit1.x is no longer actively maintained so please upgrade to 'retrofit2' instead.
	        retrofit2 - HTTP client: OkHttp 3.8.0. JSON processing: Gson 2.6.1 (Retrofit 2.3.0). Enable the RxJava adapter using '-DuseRxJava[2]=true'. (RxJava 1.x or 2.x)
	        resttemplate - HTTP client: Spring RestTemplate 4.3.9-RELEASE. JSON processing: Jackson 2.9.9
	        resteasy - HTTP client: Resteasy client 3.1.3.Final. JSON processing: Jackson 2.9.9
-->
                                <library>resteasy</library>
                                <java8>true</java8>
                            </configOptions>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

to see available configOptions use java -jar ./swagger-codegen-cli.jar config-help -l java

jasonrberk avatar Oct 06 '21 19:10 jasonrberk

I don't think @antweb's proposed fix is a general fix. It will work on @antweb's example because the enum values (i.e. Cat, Dog, Lizard) are exactly the same with the class names. It won't work if the enum values and class names don't match, e.g. the enum values change into something like CAT_TYPE, DOG_TYPE, LIZARD_TYPE.

johnlinp avatar Nov 10 '21 18:11 johnlinp

I'm also experiencing this issue.

dnievas-tr avatar Feb 14 '22 15:02 dnievas-tr

Same here as well

LogicOscar avatar Dec 09 '22 00:12 LogicOscar

Still facing this issue in 2023 :(

CSALS avatar Oct 14 '23 04:10 CSALS

Same here

bedaka avatar Nov 28 '23 11:11 bedaka

Same here

javabean68 avatar Dec 16 '23 12:12 javabean68

I ran into the same problem yesterday. Any ideas or plans?

jesudornenkrone avatar May 08 '24 07:05 jesudornenkrone

I am also experiencing same issue

kunalpmj avatar Jun 04 '24 06:06 kunalpmj

Same...

Alamonall avatar Jun 10 '24 13:06 Alamonall