Skip to content

Fix/scope the Scalar filter to the Scalar starters - #3389

Open
awinishere wants to merge 3 commits into
springdoc:mainfrom
awinishere:fix/scalar-disable-filter-scope
Open

awinishere wants to merge 3 commits into
springdoc:mainfrom
awinishere:fix/scalar-disable-filter-scope

Conversation

@awinishere

@awinishere awinishere commented Oct 17, 2026 •

Copy link
Copy Markdown

Problem

springdoc-openapi-starter-common registers an AutoConfigurationImportFilter that drops Scalar's
own auto-configurations. That module is a dependency of every starter, so applications using the
Swagger UI or the API-only starter lost the standalone Scalar integration too, with no Springdoc
Scalar controller replacing it: the configured Scalar path answered 404.

Change

The registration moves into the META-INF/spring.factories of each Springdoc Scalar starter, so it
applies exactly where a Springdoc Scalar controller replaces the standalone one. This is the first
option suggested in #3387. No logic changed ScalarDisableAutoConfiguration stays in
starter-common and still excludes both auto-configurations (the file move shows as R100,
byte-identical).

Both auto-configurations stay excluded together on purpose: Scalar's reactive auto-configuration has
no @ConditionalOnWebApplication, and both sides declare the bean scalarWebMvcController on
${scalar.path}. Letting the standalone one survive next to a Springdoc Scalar starter fails startup:

BeanDefinitionOverrideException: Invalid bean definition with name 'scalarWebMvcController' ...
already defined in [com/scalar/maven/webmvc/ScalarWebMvcAutoConfiguration.class]

Verified end to end

Same Boot 4.1.0 app (com.scalar.maven:scalar-webmvc:0.6.80, scalar.path=/docs), only the springdoc
dependency / filter registration changes:

springdoc /docs
3.1.0 (released) 404 — the reported bug
this branch 200, served by com.scalar.maven.webmvc.ScalarWebMvcController
this branch + filter registered manually by the app 404 — confirms the filter was the cause
starter-webmvc-scalar + standalone auto-config force-@Imported startup fails (the #3084 guard is real)
starter-webmvc-scalar + standalone (normal) 200, served by the Springdoc controller ("url":"http://localhost:8098/v3/api-docs")

/v3/api-docs, /swagger-ui/index.html and business endpoints stayed 200 in every scenario.

Behaviour change

The standalone integration is enabled by default (scalar.enabled uses matchIfMissing=true);
opt out with scalar.enabled=false. Also worth documenting: the standalone page needs scalar.url,
otherwise it renders a demo spec hosted on registry.scalar.com with telemetry: true, so the
visitor's browser makes a third-party request. The Springdoc controller derives the URL from the
request and has no such default.

Tests

New: ScalarDisableAutoConfigurationTest (starter-common), ScalarStarterRegistersTheDisableFilterTest
(both starters), SpringDocApp20Test (webmvc-scalar, the standalone integration must not survive next
to the Springdoc controller)

Fixes #3387

cf7d7c7 raised swagger-core without updating this expected result;
d78abd9 did update it for 2.2.54.
The filter was registered in starter-common, a dependency of every starter, so it
also dropped the standalone Scalar integration for Swagger UI and API-only users
(springdoc#3387). Each Scalar starter now registers it, where the duplicate bean definition
would otherwise fail startup (springdoc#3084).

Fixes springdoc#3387
@Mattias-Sehlstedt

Copy link
Copy Markdown
Contributor

To my knowledge the test change should not be necessary, since the date change which I did in d78abd9 was to remove springdoc pinning the type to string. We instead cede the resolving to swagger-core, which resolves it to partial-time by default. The type should only become time-local based upon an opt-in, which is described in swagger-api/swagger-core#5184.

The Scalar fix should not carry a change to unrelated tests.
@awinishere

Copy link
Copy Markdown
Author

To my knowledge the test change should not be necessary, since the date change which I did in d78abd9 was to remove springdoc pinning the type to string. We instead cede the resolving to swagger-core, which resolves it to partial-time by default. The type should only become time-local based upon an opt-in, which is described in swagger-api/swagger-core#5184.

That makes sense my apologies for the extra change. the branch is now just the Scalar fix.
Thanks for the review.

This branch has not been deployed

No deployments
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.

Scalar auto-configuration is excluded even without a Springdoc Scalar starter

2 participants