fix: manage the OpenAPI stack so Swagger cannot split into a NoSuchMethodError - #7
Merged
Merged
Conversation
Links spec 003 to issue #6. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The parent managed springdoc-openapi-starter-webmvc-ui 2.8.17 but none of the Swagger artifacts springdoc is built against, so Swagger floated and was resolved by nearest-wins mediation in every consuming project. The failure that motivated this is not springdoc calling a newer Swagger. It is Swagger calling itself across a version boundary: a library that uses only the annotations declares only swagger-annotations-jakarta, its declaration beats the 2.2.47 springdoc contributes two levels down, and swagger-core 2.2.47 then executes invokeinterface io/swagger/v3/oas/annotations/media/Schema.$dynamicRef against annotations 2.2.29, where that member does not exist. A consuming project hit exactly this and had to pin springdoc back to 2.8.6. - Import springdoc-openapi-bom, replacing the hand-managed single starter and making every springdoc starter usable without a version. - Import swagger-bom, which is what actually fixes the split. The official springdoc BOM manages springdoc artifacts only and deliberately says nothing about Swagger. - Manage org.webjars:swagger-ui, which no BOM covers and which belongs to the same coupled set. - Document the lockstep at both places a maintainer would look: a comment on the properties and a README maintenance section naming the exact POM and properties to read for a future bump. swagger-bom was first published at 2.2.47, so swagger.version has a floor. That constraint was found during implementation and is recorded in the POM comment and the README. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Adds the implementation steps and the coverage mapping, and folds the measurements back into the spec: 15 of 18 scenarios were confirmed against throwaway probe projects, including a counter-probe against the unmodified parent so the check cannot pass vacuously. Two findings changed the documents rather than being silently accepted. The swagger-bom floor of 2.2.47 is now in design.md and behaviors.md, including the consequence that a child overriding swagger.version downwards gets a model-building failure. The Spring Boot overlap scenario now names what spring-boot-dependencies 3.5.14 actually manages under org.webjars, so the claim is checkable instead of merely asserted. docs/TODO.md records the javax and JAX-RS reach of swagger-bom as confirmed rather than suspected, and marks spec 003 done in the index. Closes #6 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
hendrikebbers
force-pushed
the
fix/003-openapi-stack-versions
branch
from
September 10, 2026 17:06
2199e73 to
0ccce73
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The parent managed
springdoc-openapi-starter-webmvc-ui2.8.17 but none of theSwagger artifacts springdoc is built against, so Swagger floated and was resolved by
nearest-wins mediation in every consuming project. A project using this parent hit
the resulting failure and had to pin springdoc back to 2.8.6 to work around it.
The failure is inside Swagger, not between springdoc and Swagger
Worth stating precisely, because it changes what the fix has to cover. springdoc
2.8.17's compiled classes reference no Swagger member missing from 2.2.29 —
verified across all 285 classes of the three starters. springdoc is not the caller
that fails.
Swagger breaks itself. A library that uses only the Swagger annotations declares only
swagger-annotations-jakarta— the normal thing for such a library to do — and thatdeclaration sits one level from the application, beating the 2.2.47 springdoc
contributes two levels down via
swagger-core-jakarta.swagger-core-jakartaitselfhas no competitor and stays at 2.2.47. The stack splits along exactly the artifact
boundary a well-behaved library would touch, and then:
NoSuchMethodError. This is also why pinning a single artifact would not have beenenough — the three move as a unit.
Spec
docs/specs/003-openapi-stack-versions/docs/specs/003-openapi-stack-versions/design.mddocs/specs/003-openapi-stack-versions/behaviors.mddocs/specs/003-openapi-stack-versions/steps.mdChanges
swagger-bomimport — the part that actually fixes the split. Covers all 14Swagger coordinates, so a future springdoc pulling in another Swagger module is
covered without maintaining an artifact list.
springdoc-openapi-bomimport — replaces the hand-managed single starter.It contributes nothing to the bug: it manages springdoc's own artifacts and
deliberately says nothing about Swagger. It is imported so the vendor's list
replaces ours, and children can use the webflux and scalar starters without a
version.
org.webjars:swagger-uimanaged — no BOM covers it and it belongs to the samecoupled set.
maintainer would look: a comment on the properties themselves and a README
maintenance section naming the exact POM and properties to read for a bump.
Rejected: importing
org.springdoc:springdoc-openapi(the aggregator) would make thelockstep mechanical, but it is springdoc's internal build structure rather than a
published contract, and it also manages jjwt, scalar and spring-cloud-function.
Verification
Measured against throwaway probe projects, then removed:
annotations 2.2.29besidecore 2.2.47— the split reproduced2.2.47springdoc-openapi-starter-webflux-uiwith no version2.8.17— previously impossibleswagger-annotations-jakarta2.2.292.2.29— the documented limit ofdependencyManagement<version>removed2.2.47<swagger.version>2.2.50</swagger.version>swagger-annotationsandswagger-jaxrs2-jakarta2.2.47— the BOM's wider reach, confirmed15 of 18 scenarios measured. The counter-probe against the unmodified parent
exists so the check cannot pass vacuously.
Constraint found during implementation
io.swagger.core.v3:swagger-bomwas first published at 2.2.47 — every earlierversion 404s, and the published range is 2.2.47 to 2.2.55. The version this change
needs is the very first one that has a BOM at all. Consequences, now recorded in the
POM comment, the design and the README: a springdoc release pinned to an older
Swagger could not use the import, and a child overriding
swagger.versionbelow2.2.47 gets an explicit model-building failure rather than an override. Declaring the
artifact directly with a
<version>is unaffected.Known limits
and is neither fixed nor warned.
spring-services-coreis the known case; trackedin
docs/TODO.md.publish a split stack to every child at once, and this parent's own build would not
notice — it has no Java sources. Also tracked in
docs/TODO.md.version, so that entry is not demonstrated as load-bearing.
Note for the reviewer
This branch,
feat/002-pinned-line-endingsandfeat/001-reproducible-build-timestampeach add a README section and will conflict there on the second and third merge. The
conflicts are additive — all sections are kept.
Closes #6
🤖 Generated with Claude Code