Skip to content

fix(spring): avoid duplicate Tag import when a model is named Tag - #24555

Open
donald wants to merge 1 commit into
OpenAPITools:masterfrom
donald:fix/spring-tag-model-name-clash
Open

fix(spring): avoid duplicate Tag import when a model is named Tag#24555
donald wants to merge 1 commit into
OpenAPITools:masterfrom
donald:fix/spring-tag-model-name-clash

Conversation

@donald

@donald donald commented Aug 1, 2026

Copy link
Copy Markdown

Fixes #24554

What

If the spec defines a model named Tag and an api uses it, the generated Spring api imported both the
model and io.swagger.v3.oas.annotations.tags.Tag. Two single-type-imports of the same simple name is a
hard javac error, so the generated code did not compile.

// before
import org.openapitools.model.Tag;                    // line 8
import io.swagger.v3.oas.annotations.tags.Tag;        // line 18
@Tag(name = "pets", description = "the pets API")
public interface TagApi {
    default ResponseEntity<Tag> getTag(...)
error: a type with the same simple name is already defined by the single-type-import of Tag
// after
import org.openapitools.model.Tag;
@io.swagger.v3.oas.annotations.tags.Tag(name = "pets", description = "the pets API")
public interface TagApi {
    default ResponseEntity<Tag> getTag(...)

This is not an ambiguity a wildcard import could resolve — both imports are explicit.

How

SpringCodegen.postProcessOperationsWithModels sets qualifySwaggerTagAnnotation when the file being
generated imports the model Tag; JavaSpring/api.mustache and JavaSpring/apiController.mustache then
emit the fully qualified annotation and skip the annotation import.

The model import is kept — it is the type actually used in the signatures.

Scoping matters here. My first attempt keyed off "the spec contains a model named Tag" and stored the
flag in additionalProperties. That is both too broad and sticky across files: the petstore sample defines
a Tag model, so every spring sample got the qualified annotation even though most api files never
import the model. It rewrote 171 sample files and broke testNoRequestMappingAnnotation and
testNoRequestMappingAnnotation_spring_cloud_default. The committed version checks
objs.getImports() for modelPackage() + ".Tag" and stores the flag per operations map, so only the files
that actually hit the clash change.

Testing

  • SpringCodegenTest.modelNamedTagDoesNotClashWithSwaggerTagAnnotation — asserts the annotation import is
    gone, the annotation is fully qualified, and the model import is still present. Verified that this test
    fails without the fix.
  • Full SpringCodegenTest (294 tests) passes, including the two cases the over-broad first attempt broke.
  • Regenerated all 787 sample configs (./bin/generate-samples.sh ./bin/configs/*.yaml) and
    ./bin/utils/export_docs_generators.shno diff.

Note on the full test run: mvn test on modules/openapi-generator reports one pre-existing failure,
OpenApiSchemaValidationsTest.testNullTypeInOas31_noWarning. It fails identically on unmodified
master (4aed9c1c635) — verified by reverting the patch and re-running — and is unrelated to this change.

PR checklist

  • Read the contribution guidelines.
  • Run the following to build the project and update samples:
    ./mvnw clean package || exit
    ./bin/generate-samples.sh ./bin/configs/*.yaml || exit
    ./bin/utils/export_docs_generators.sh || exit
    
    Commit all changed files.
    (Both scripts were run; neither produced any change, so there is nothing to commit beyond the fix and its test.)
  • File the PR against the correct branch: master
  • If your PR is targeting a particular programming language, @mention the technical committee members, so they are more likely to review the pull request.

Java/Spring technical committee:
@bbdouglas @sreeshas @jfiala @lukoyanov @cbornet @jeff9finger @karismann @Zomzog @lwlee2608 @martin-mfg

🤖 Generated with Claude Code


Summary by cubic

Fixes a compile error in generated Spring APIs when a schema is named Tag by fully qualifying the Swagger @Tag annotation only in files that import the model Tag. This avoids duplicate single-type imports and restores compilation.

  • Bug Fixes
    • Detect the clash per API file by checking for modelPackage.Tag imports and set qualifySwaggerTagAnnotation in SpringCodegen.postProcessOperationsWithModels.
    • In JavaSpring/api.mustache and JavaSpring/apiController.mustache, render @io.swagger.v3.oas.annotations.tags.Tag and skip its import when flagged; keep org.openapitools.model.Tag imported.
    • Added test modelNamedTagDoesNotClashWithSwaggerTagAnnotation; all Spring tests pass and regenerating samples shows no diff.

Written for commit 256d4e5. Summary will update on new commits.

Review in cubic

If the spec defines a model named `Tag` and an api uses it, the generated
api imported both the model and io.swagger.v3.oas.annotations.tags.Tag.
Two single-type-imports of the same simple name is a hard javac error, so
the generated code did not compile:

    import org.openapitools.model.Tag;
    import io.swagger.v3.oas.annotations.tags.Tag;
    @tag(name = "pets", ...)
    public interface TagApi {
        default ResponseEntity<Tag> getTag(...)

    error: a type with the same simple name is already defined by the
           single-type-import of Tag

The model import is the one that matters -- it is the type used in the
signatures -- so reference the annotation by its fully qualified name and
skip importing it.

The detection is per api file, driven by that file's own imports rather
than by "the spec contains a model named Tag": the petstore sample defines
a Tag model but most of its api files never import it, and qualifying the
annotation there would be needless churn (it rewrote 171 sample files and
broke two existing SpringCodegenTest cases before being scoped down).

Regenerating all 787 sample configs produces no diff.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 5 files

Re-trigger cubic

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG][Spring] Model named Tag collides with @Tag annotation import, generated code does not compile

1 participant