[spring] fix schema named "Schema" colliding with the swagger2 annotation - #24901
[spring] fix schema named "Schema" colliding with the swagger2 annotation#24901GianniGiglio wants to merge 1 commit into
Conversation
…tion
A schema named "Schema" produces a model that cannot be referenced by the
generated code, because AbstractJavaCodegen registers
importMapping.put("Schema", "io.swagger.v3.oas.annotations.media.Schema")
and DefaultGenerator consults importMapping before toModelImport(). The model
import is therefore silently replaced by the annotation import, so the bare
"Schema" type in api signatures resolves to the annotation. Emitting the model
import instead does not help on its own: it then clashes with the annotation
import the templates add, and in the model file with the declared class of the
same name, which is a compile error either way (JLS 7.5.1).
Drop the default mapping when a model of that name exists so the model keeps the
simple name, and fully qualify the annotation at its usage sites rather than
importing it. An explicit --import-mappings entry pointing at a different class
is left untouched.
Verified against the spec from the issue: generated project fails to compile on
master with 15 errors and compiles cleanly with this change, for both
interfaceOnly=true and the api controller variant. Regenerating all 71 spring
and java-camel sample configs produces no diff, since the qualification only
applies when the collision is present.
Fixes OpenAPITools#16584
|
thanks for the PR cc @cachescrubber (2022/02) @welshm (2022/02) @MelleD (2022/02) @atextor (2022/02) @manedev79 (2022/02) @javisst (2022/02) @borsch (2022/02) @banlevente (2022/02) @Zomzog (2022/09) @martin-mfg (2023/08) @KannaKim (2026/07) |
|
a workaround is to rename the model to something else using the |
| public void preprocessOpenAPI(OpenAPI openAPI) { | ||
| super.preprocessOpenAPI(openAPI); | ||
|
|
||
| // A schema named "Schema" collides with io.swagger.v3.oas.annotations.media.Schema. Two |
There was a problem hiding this comment.
Would it make sense to break this check out into a more generic
handleSchemaNameCollision(String name, String import, String schemaKey, String importKey)and then that you do
handleSchemaNameCollision("Schema", SWAGGER2_ANNOTATION_SCHEMA_IMPORT, SCHEMA_ANNOTATION, IMPORT_SCHEMA_ANNOTATION)?
This should somewhat allow someone to fix this issue for similar issues, and it would also allow us to have a more generic description of the cause as javadoc on handleSchemaNameCollision rather than tying the description exactly to the reported scenario
Fixes #16584
A schema named
Schemagenerates a model that the generated code cannot reference.AbstractJavaCodegenregisters:and
DefaultGeneratorconsultsimportMappingbeforetoModelImport()(getAllImportsMappings, and the model path aroundDefaultGenerator:1794). The model import is therefore silently replaced by the annotation import, and the bareSchematype in api signatures binds to the annotation instead of the model:Emitting the model import instead does not fix it on its own: it then clashes with the annotation import the templates add, and in the model file with the declared class of the same name. Two single-type imports for the same simple name, and an import conflicting with a type declared in the same compilation unit, are both compile errors (JLS 7.5.1).
Change
SpringCodegen.preprocessOpenAPIdetects a model namedSchemaand drops the defaultimportMappingentry so the model keeps the simple name. An explicit--import-mappingsentry pointing at a different class is left untouched (covered by a test).swagger2SchemaAnnotation,importSwagger2SchemaAnnotation). This is confined toJavaSpringtemplates:api,apiController,model,pojo,lombokAnnotation.The collision detection compares against
toModelName(...), somodelNamePrefix/modelNameSuffixare honoured, and it runs afterInlineModelResolver.flattenso inline-promoted models are covered.Verification
Using the spec from the issue:
masterBUILD FAILURE— 15 compile errors, e.g.org.openapitools.model.Schema is already defined in this compilation unitBUILD SUCCESSVerified for both
interfaceOnly=trueand the api controller variant.SpringCodegenTest: 339/339 pass.spring*andjava-camel*sample configs produces no diff — the qualification only applies when the collision is actually present, so existing output is byte-identical.Note on the modified test
annotationLibraryDoesNotCauseImportConflictsInSpringWithAnnotationLibraryasserted that the model file containsimport io.swagger.v3.oas.annotations.media.Schema;. Its spec (issue21991.yaml) names a schemaSchema, so that assertion pins output that does not compile (the 15 errors above). It now asserts the fully-qualified form instead. Its siblingannotationLibraryDoesNotCauseImportConflictsInSpring(theannotationLibrary=nonepath fixed by #21992 / #22045) passes unchanged.This completes the half that #21991 explicitly deferred — quoting that reporter:
#21992 and #22045 fixed only the
annotationLibrary=nonepath; the defaultswagger2path, where the collision is unavoidable, is this issue.Scope
Deliberately limited to the
springgenerator and theSchemakey.AbstractJavaCodegenputsFile,Date,Map,List,SetandUUIDin the same map, so a model namedFilecurrently resolves tojava.io.File— the same class of bug, but changing it means real behaviour changes and sample churn. Happy to widen this toAbstractJavaCodegenand the other Java generators (JavaClientCodegenandJavaJerseyServerCodegencallmodel.imports.add("Schema")and would need matching template work) if you'd prefer that in one pass.Summary by cubic
Fixes the Spring generator so a schema named
Schemagenerates code that compiles, instead of a model that cannot be referenced.Bug Fixes
io.swagger.v3.oas.annotations.media.Schemaannotation import, so API signatures referenced the annotation instead of the model, and emitting both imports caused compile errors.Schema, and the swagger2 annotation is fully qualified at its usage sites in the Spring templates.--import-mappingsentry forSchemapointing to a different class is left untouched.springandjava-camelsamples produced no diff.Written for commit 8dfaa1f. Summary will update on new commits.