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...