[BUG] java.util.Locale is mixed with custom component if named "Locale"
Description
Since 7.15.0 I have compiler errror for the generated code for my openapi spec. The spec contains a custom component "Locale" ... in the past this was working fine.
openapi-generator version
7.16.0+
OpenAPI declaration file content or url
If you post the code inline, please wrap it with
openapi: 3.0.1
info:
version: '1.27'
title: Example to show effects with Locale
description: This definition was taken from a real world api which was working until 7.15.0.
paths:
/api/v1/brain/product/localizations/{productId}/{version}:
post:
operationId: getProductLocalizations
summary: Get localization data for a product.
parameters:
- name: productId
in: path
description: Provide the id of the product.
required: true
schema:
type: string
minLength: 1
example: 1LE1X
- name: version
in: path
description: Provide the version of the product. Could be 'LATEST' to retrieve the newest version.
required: true
schema:
type: string
minLength: 1
example: LATEST
requestBody:
description: Required payload for the request.
required: true
content:
application/json:
examples:
0 - Only language 'en':
description: Language 'en' without country.
summary: Only language 'en'
value:
locales:
- language: en
1 - Multiple locales:
description: Locale 'EN_en' and 'DE_de'.
summary: Multiple locales
value:
locales:
- country: EN
language: en
- country: DE
language: de
schema:
$ref: '#/components/schemas/GetProductLocalizationsPayload'
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/GetProductLocalizationsResult'
'400':
description: Bad Request
content:
application/problem+json:
schema:
$ref: '#/components/schemas/ProblemDetail'
'401':
description: Unauthorized
content:
application/problem+json:
schema:
$ref: '#/components/schemas/ProblemDetail'
'403':
description: Forbidden
content:
application/problem+json:
schema:
$ref: '#/components/schemas/ProblemDetail'
'404':
description: Not found
content:
application/problem+json:
schema:
$ref: '#/components/schemas/ProblemDetail'
'500':
description: Internal Server Error
content:
application/problem+json:
schema:
$ref: '#/components/schemas/ProblemDetail'
security:
- basicScheme: []
tags:
- service
- read
- v1.24
components:
schemas:
CsticLocalization:
description: Localization data of a Cstic.
type: object
properties:
longText:
type: string
name:
type: string
numberPattern:
type: string
taggedTexts:
$ref: '#/components/schemas/TaggedTexts'
text:
type: string
unit:
type: string
values:
type: array
items:
$ref: '#/components/schemas/Localization'
ElementLocalization:
description: Localization data of an Element.
type: object
properties:
cstics:
type: array
items:
$ref: '#/components/schemas/CsticLocalization'
longText:
type: string
name:
type: string
taggedTexts:
$ref: '#/components/schemas/TaggedTexts'
text:
type: string
GetProductLocalizationsPayload:
description: Container for locales.
type: object
properties:
locales:
type: array
items:
$ref: '#/components/schemas/Locale'
GetProductLocalizationsResult:
description: Result for product localization.
type: object
properties:
error:
type: string
localizations:
type: array
items:
$ref: '#/components/schemas/ProductLocalization'
productId:
type: string
requestedLocales:
type: array
items:
$ref: '#/components/schemas/Locale'
returnedFailedLocales:
type: array
items:
$ref: '#/components/schemas/Locale'
returnedSuccessfulLocales:
type: array
items:
$ref: '#/components/schemas/Locale'
version:
type: string
Locale:
description: Locale for localization.
type: object
properties:
country:
type: string
language:
type: string
Localization:
description: Localization data.
type: object
properties:
longText:
type: string
name:
type: string
taggedTexts:
$ref: '#/components/schemas/TaggedTexts'
text:
type: string
ProblemDetail:
type: object
properties:
detail:
type: string
instance:
type: string
format: uri
properties:
type: object
additionalProperties:
type: object
status:
type: integer
format: int32
title:
type: string
type:
type: string
format: uri
ProductLocalization:
description: Localization data of a Product.
type: object
properties:
elements:
type: array
items:
$ref: '#/components/schemas/ElementLocalization'
globalCstics:
type: array
items:
$ref: '#/components/schemas/CsticLocalization'
locale:
$ref: '#/components/schemas/Locale'
longText:
type: string
messages:
type: array
items:
$ref: '#/components/schemas/Localization'
name:
type: string
taggedTexts:
$ref: '#/components/schemas/TaggedTexts'
text:
type: string
TaggedText:
description: A text with free useable tags. See TextTag enum for known tags.
type: object
properties:
tags:
type: array
items:
type: string
text:
type: string
TaggedTexts:
type: object
properties:
texts:
type: array
items:
$ref: '#/components/schemas/TaggedText'
securitySchemes:
basicScheme:
scheme: basic
type: http
tags:
- description: Commmon service operations
name: service
- description: Write operations
name: write
- description: Read operations
name: read
Generation Details
I'm using this maven plugin configuration ...
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>7.17.0</version>
<configuration>
<generatorName>java</generatorName>
<addCompileSourceRoot>true</addCompileSourceRoot>
<generateModelTests>false</generateModelTests>
<generateApiTests>false</generateApiTests>
<skipOverwrite>false</skipOverwrite>
<indentSize>2</indentSize>
<lineLength>200</lineLength>
<verbose>false</verbose>
<skipIfSpecIsUnchanged>false</skipIfSpecIsUnchanged>
<removeOperationIdPrefix>false</removeOperationIdPrefix>
<operationIdNameMappings>original</operationIdNameMappings>
<skipValidateSpec>false</skipValidateSpec>
<strictSpec>true</strictSpec>
<configOptions>
<additionalModelTypeAnnotations><![CDATA[ @SuppressWarnings("all") @com.fasterxml.jackson.annotation.JsonIgnoreProperties(ignoreUnknown = true) ]]></additionalModelTypeAnnotations>
<enumUnknownDefaultCase>true</enumUnknownDefaultCase>
<library>resttemplate</library>
<java8>true</java8>
<dateLibrary>java8</dateLibrary>
<failOnUnknownProperties>false</failOnUnknownProperties>
<sortModelPropertiesByRequiredFlag>false</sortModelPropertiesByRequiredFlag>
<sortParamsByRequiredFlag>false</sortParamsByRequiredFlag>
<skipSortingOperations>true</skipSortingOperations>
<generateClientAsBean>false</generateClientAsBean>
<useJakartaEe>true</useJakartaEe>
</configOptions>
</configuration>
...
Steps to reproduce
I will provide a unit test via org.openapitools.codegen.java.JavaClientCodegenTest.testApiComponentNamedLocale()
Suggest a fix
Not sure .. may this "Locale" is now a forbidden component name? If not the generator need a fix use everywhere the full qualified name of the custom component "Locale" type .. to avoid mixing with java.util.Locale type.
what about using model name mapping option to workaround the issue?
https://github.com/OpenAPITools/openapi-generator/blob/master/docs/customization.md#name-mapping
@wing328 until yet I was not aware of this ... thanks I will read this asap.
Update: the bug here is not about properties ... the whole type is incorrect So I guess mapping is not an option
But beside that workaround I think its worth to check why this happens since > 7.15.0.
Maybe this is not the fault of the openapi-generator ... I will try to find out why this happens.
Does anyone here can give me an hint where the "real" full qualified name resolution happens for the collected "imports". As far as I see all the "import" just simple names during "processing" the api-spec... But then in the final step where the java-files is generated via template the imports become "full". For example in my provided test ...
package org.openapitools.client.model;
import java.util.Objects;
import java.util.Arrays;
import java.util.Locale; // <<<<<<<<<<<<<<<<< where is "java.util." added to "Locale"?
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonTypeName;
import com.fasterxml.jackson.annotation.JsonValue;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.openapitools.client.model.Locale;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.fasterxml.jackson.annotation.JsonTypeName;
@wing328 can u drop me some hints please? I have the feeling that the code where the java-imports are collected the difference between custom-types (from the openapi-spec) and (standard) java-types (and also other "standards" like jackson types) are not really clear. In the code there are simply strings and most of the time not full qualified. With some more insights I may can think about a better solution.
Hmmm .. anyone else can support here maybe??
Hi @ahoehma ! This is something I identified also, see #22313 .
@ahoehma is this the failing assertion?
JavaFileAssert.assertThat(files.get("Locale.java")).isNormalClass()
.hasNoImports("java.util.Locale");
Because if it is, then it is the added import in 7.15.0 - 7.16.0 that is causing this to fail.
@ahoehma is this the failing assertion?
JavaFileAssert.assertThat(files.get("Locale.java")).isNormalClass() .hasNoImports("java.util.Locale"); Because if it is, then it is the added import in 7.15.0 - 7.16.0 that is causing this to fail.
Exactly. And to import java.lang.Locale would pretty okay if this is not conflicting with a "com.custom.Locale" class. My test is, with the new knowledge that java.lang.Locale is always imported, not correct anymore. I was trying to define a test which shows this conflict. I can try to adapt the test to show that "my own" Locale is used.
But wait a second .. do you tell me that "java.lang.Locale" is also imported INTO my "own" Locale class... then ... this make no sense in my case 💯
@Chrimle ... I build your PR locally and used your version of open-api-generator and good news ... my compiler errors because of "Locale" are gone! Yippi! 👍