Skip to content

chore: upgrade springdoc-openapi to 3.1.0 for Spring Data 4 compatibility - #2112

Merged
netomi merged 1 commit into
mainfrom
chore/upgrade-springdoc-openapi-3.1.0
Aug 31, 2026
Merged

chore: upgrade springdoc-openapi to 3.1.0 for Spring Data 4 compatibility#2112
netomi merged 1 commit into
mainfrom
chore/upgrade-springdoc-openapi-3.1.0

Conversation

@netomi

@netomi netomi commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Why

springdoc-openapi 2.8.13's QuerydslPredicateOperationCustomizer (pulled in transitively via springdoc-openapi-starter-webmvc-uispringdoc-openapi-starter-common) was compiled against a spring-data-commons version older than 4.0, where TypeInformation lived in org.springframework.data.util. This project resolves spring-data-commons:4.0.6 (matching Spring Boot 4.0.7), where TypeInformation moved to org.springframework.data.core — a package that class no longer knows about.

Regular application startup never reflectively introspects that customizer's method signatures, so the incompatibility is invisible in normal operation. It surfaces under Spring's AOT processing: PersistenceAnnotationBeanPostProcessor's more aggressive bean introspection during AOT context refresh walks the class and throws NoClassDefFoundError for the now-nonexistent org.springframework.data.util.TypeInformation. (Found while investigating why processAot/processTestAot weren't even registered in this build — turned out org.springframework.boot.aot must be applied as a separate plugin from org.springframework.boot, which is a separate finding not included in this PR.)

What

Bumps springdoc to 3.1.0, which ships that same customizer recompiled against the moved TypeInformation. Verified via bytecode inspection against the published jars (not just changelog reading) that:

  • The incompatible class now references org.springframework.data.core.TypeInformation.
  • This project's own springdoc usage (GroupedOpenApi, OpenApiCustomizer, OperationCustomizer in DocumentationConfig) is unchanged in 3.1.0's bytecode — no source changes needed.

Verification

  • Compiles clean.
  • DocumentationConfigTest passes.
  • Full test suite: 1061/1061 passing.
  • Re-tested processTestAot (with the AOT plugin applied locally, not part of this PR) — the TypeInformation failure is gone. A separate, unrelated Spring Data AOT class-generation limitation remains when processing many @SpringBootTest classes that share a context configuration, so AOT itself isn't usable here yet regardless of this fix — but that's no longer blocked on this specific incompatibility.

Note: springdoc-openapi 3.1.0 targets the Spring Boot 4.1 line's BOM; this project pins Spring Boot 4.0.7. This is a minor-version gap that Spring Boot's own dependency management should reconcile transitively (confirmed by the green full suite), same as any other dependency slightly ahead of the pinned Boot BOM.

🤖 Generated with Claude Code

…lity

springdoc-openapi 2.8.13's QuerydslPredicateOperationCustomizer class
(part of springdoc-openapi-starter-webmvc-ui's transitive
springdoc-openapi-starter-common) was compiled against spring-data-commons
< 4.0, where TypeInformation lived in org.springframework.data.util. This
project resolves spring-data-commons 4.0.6 (matching Spring Boot 4.0.7),
where TypeInformation moved to org.springframework.data.core - a package
that no longer exists from that customizer's point of view.

Regular application startup never reflectively introspects that
customizer's method signatures, so the incompatibility stays invisible
in normal operation. It does surface under Spring's AOT processing
(tried while investigating why processTestAot/processAot weren't wired
up, since org.springframework.boot.aot must be applied separately from
org.springframework.boot): PersistenceAnnotationBeanPostProcessor's more
aggressive bean introspection during AOT context refresh walks that
class and throws NoClassDefFoundError for the no-longer-existent
org.springframework.data.util.TypeInformation.

springdoc-openapi 3.1.0 (targeting the Spring Boot 4.1 line, still
binary-compatible here per this project's own Spring Boot BOM/dependency
management) ships that same customizer recompiled against the moved
TypeInformation. Verified the application's own springdoc usage
(GroupedOpenApi, OpenApiCustomizer, OperationCustomizer in
DocumentationConfig) is unchanged in 3.1.0's bytecode - no source
changes needed - and confirmed the fix: compiles clean, full test suite
green (1061/1061), and processTestAot no longer fails on TypeInformation
(a separate, unrelated Spring Data AOT class-generation limitation
remains, tracked separately - AOT itself is not yet usable here).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@netomi
netomi requested review from cstamas and a lite review from Copilot August 31, 2026 08:32

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

Pull request overview

Updates the server’s OpenAPI/Swagger integration dependency to resolve a Spring Data 4 compatibility issue during Spring AOT processing (caused by a moved TypeInformation type).

Changes:

  • Bump springdoc-openapi (via version catalog) from 2.8.13 to 3.1.0.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@netomi

netomi commented Aug 31, 2026

Copy link
Copy Markdown
Contributor Author

btw. this dependency bump is necessary to support Spring Boot JPA AOT processing as the currently used version is not fully compatible with Spring Boot 4.

@cstamas

cstamas commented Aug 31, 2026

Copy link
Copy Markdown
Member

Note: our script uses Toolbox w/ --artifactVersionSelectorSpec="minor()" that means it was showing only minor version upgrades (it was limiting itself), even if there was new major available. We may want to parametrize this?

@netomi

netomi commented Aug 31, 2026

Copy link
Copy Markdown
Contributor Author

That dep update was missed when we did the spring boot 4 upgrade. In general checking minor version updates is fine, maybe we can add a flag to the script to also check if there are major updates available which anyway have to be manually vetted.

@netomi
netomi merged commit 46335e7 into main Aug 31, 2026
6 checks passed
@netomi
netomi deleted the chore/upgrade-springdoc-openapi-3.1.0 branch August 31, 2026 11:21
netomi added a commit that referenced this pull request Sep 2, 2026
Upgrading springdoc to 3.1.0 (#2112) also changed the spec version it emits:
springdoc 3.x defaults springdoc.api-docs.version to OPENAPI_3_1, where 2.8.13
defaulted to OPENAPI_3_0. That was a side effect of the bump rather than a
decision, and it silently dropped a field from the document.

new Schema<>().type("integer") sets only the legacy string `type` and leaves the
3.1 `types` set null, and a 3.1 document does not serialize the former. The four
rate limit headers have therefore been documented with no type at all since the
upgrade. Building them through IntegerSchema populates both fields, so they keep
a type whichever version springdoc emits.

The dev configuration pins api-docs back to 3.0. Beyond restoring the document
as it was, it silences a warning that OpenAPI 3.1 draws out of swagger-core
2.2.52 on every schema springdoc clones:

  SpringDocUtils : Json Processing Exception occurred: Cannot construct instance
  of `java.util.HashSet` [...] from String value ('integer')
  (through reference chain: io.swagger.v3.oas.models.media.JsonSchema["type"])

Its 3.1 mapper writes a single type as a bare string but only reads an array
back, so cloneViaJson cannot re-read what it just wrote. It logs and falls back
to the original object, so the document still renders. A schema with two types
serializes as an array and round-trips fine, which is why only some schemas trip
it. Nothing in this repository can fix that asymmetry; only avoiding 3.1 avoids
it.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.

3 participants