openapi-generator
openapi-generator copied to clipboard
[java] Compilation failure when 'discriminator' is introduced
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
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
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).
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"
}
}
}
Any update?
Feel free to propose a pull request
This issue appears to be fixed in 4.1.3.
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());
Any update on this?
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"
}
]
},
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
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.
I'm also experiencing this issue.
Same here as well
Still facing this issue in 2023 :(
Same here
Same here
I ran into the same problem yesterday. Any ideas or plans?
I am also experiencing same issue
Same...