Summary
SpringDocWebMvcConfiguration is annotated @ConditionalOnBean(SpringDocConfiguration.class) but does not declare
@AutoConfigureAfter(SpringDocConfiguration.class). The condition therefore only matches because
org.springdoc.core.configuration.SpringDocConfiguration happens to sort alphabetically before
org.springdoc.webmvc.core.configuration.SpringDocWebMvcConfiguration in Spring Boot's AutoConfigurationSorter.
Any third-party autoconfiguration that
- has a fully-qualified name sorting before
org.springdoc.core and
- orders itself around
SpringDocWebMvcConfiguration (@AutoConfigureBefore/@AutoConfigureAfter)
changes the topological sort so that `SpringDocWebMvcConfiguration``
is evaluated before SpringDocConfiguration is registered. The @ConditionalOnBean then fails, SpringDocWebMvcConfiguration is skipped, and OpenApiWebMvcResource is silently dropped.
Versions
- springdoc-openapi 3.1.0 (
springdoc-openapi-starter-common, springdoc-openapi-starter-webmvc-api)
- Spring Boot 4.1.0
- Jetty (
spring-boot-starter-jetty)
Reproduction
springdoc-repro.zip
[Generated] Minimal Spring Boot 4.1.0 + Jetty app. Dependencies are only the two springdoc starters plus one ordinary third-party auto-config (OpenApiCustomizationAutoConfiguration, @AutoConfiguration(after = SpringDocWebMvcConfiguration.class), contributing no beans).
mvn test # OpenApiMissing...Test fails; OpenApiPresent...Test (offender excluded) passes
mvn exec:java -Dexec.mainClass=com.example.springdocbug.ReproApplication
App output:
REPRO OpenApiWebMvcResource present = false (expected: true)
REPRO SpringDocWebMvcConfiguration -> match=false : @ConditionalOnBean (types: ...SpringDocConfiguration...) did not find any beans
Rename the third-party auto-config to a package that sorts after org.springdoc.core (e.g. zzz.*), or exclude it via spring.autoconfigure.exclude, andOpenApiWebMvcResource reappears.
Note: this can only be reproduced through the real @EnableAutoConfiguration / AutoConfiguration.imports
mechanism. ApplicationContextRunner + AutoConfigurations.of(...) does not apply @AutoConfigureBefore/After the same way.
Suggested fix
Declare the ordering that the @ConditionalOnBean implicitly requires, rather than relying on alphabetical order. Add to SpringDocWebMvcConfiguration:
@AutoConfigureAfter(SpringDocConfiguration.class)
The same pattern (a web/config class @ConditionalOnBean(SpringDocConfiguration.class) without a corresponding @AutoConfigureAfter) appears to apply to the WebFlux variant (SpringDocWebFluxConfiguration) and likely others.
Workaround for consumers
Depend on a custom auto-config, ordered @AutoConfigureBefore(SpringDocWebMvcConfiguration.class), that
@Imports SpringDocConfiguration (and SpringDocConfigProperties) so the bean is guaranteed to exist before the web config's condition is evaluated.
Summary
SpringDocWebMvcConfigurationis annotated@ConditionalOnBean(SpringDocConfiguration.class)but does not declare@AutoConfigureAfter(SpringDocConfiguration.class). The condition therefore only matches becauseorg.springdoc.core.configuration.SpringDocConfigurationhappens to sort alphabetically beforeorg.springdoc.webmvc.core.configuration.SpringDocWebMvcConfigurationin Spring Boot'sAutoConfigurationSorter.Any third-party autoconfiguration that
org.springdoc.coreandSpringDocWebMvcConfiguration(@AutoConfigureBefore/@AutoConfigureAfter)changes the topological sort so that `SpringDocWebMvcConfiguration``
is evaluated before
SpringDocConfigurationis registered. The@ConditionalOnBeanthen fails,SpringDocWebMvcConfigurationis skipped, andOpenApiWebMvcResourceis silently dropped.Versions
springdoc-openapi-starter-common,springdoc-openapi-starter-webmvc-api)spring-boot-starter-jetty)Reproduction
springdoc-repro.zip
[Generated]Minimal Spring Boot 4.1.0 + Jetty app. Dependencies are only the two springdoc starters plus one ordinary third-party auto-config (OpenApiCustomizationAutoConfiguration,@AutoConfiguration(after = SpringDocWebMvcConfiguration.class), contributing no beans).App output:
Rename the third-party auto-config to a package that sorts after
org.springdoc.core(e.g.zzz.*), or exclude it viaspring.autoconfigure.exclude, andOpenApiWebMvcResourcereappears.Note: this can only be reproduced through the real
@EnableAutoConfiguration/AutoConfiguration.importsmechanism.
ApplicationContextRunner+AutoConfigurations.of(...)does not apply@AutoConfigureBefore/Afterthe same way.Suggested fix
Declare the ordering that the
@ConditionalOnBeanimplicitly requires, rather than relying on alphabetical order. Add toSpringDocWebMvcConfiguration:The same pattern (a web/config class
@ConditionalOnBean(SpringDocConfiguration.class)without a corresponding@AutoConfigureAfter) appears to apply to the WebFlux variant (SpringDocWebFluxConfiguration) and likely others.Workaround for consumers
Depend on a custom auto-config, ordered
@AutoConfigureBefore(SpringDocWebMvcConfiguration.class), that@ImportsSpringDocConfiguration(andSpringDocConfigProperties) so the bean is guaranteed to exist before the web config's condition is evaluated.