Skip to content

springdoc-openapi-kotlin and springdoc-openapi-common do not agree on conditions for auto configuration #1734

Closed
@l61ronny

Description

@l61ronny

We have a big multi-module repository of several Spring Boot applications.
Some of these applications run as web apps, some are mere background services using org.springframework.boot.WebApplicationType.NONE.
Even for these background services we might (transitively) depend on springdoc-openapi.

With springdoc-openapi 1.6.9 we observe application start-up failures for our non-web apps:

Jul 07 09:23:16 our-app: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springdoc.kotlin.SpringDocKotlinConfiguration': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springdoc.core.providers.ObjectMapperProvider' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
Jul 07 09:23:16 our-app:         at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:800)
Jul 07 09:23:16 our-app:         at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:229)
Jul 07 09:23:16 our-app:         at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1372)
Jul 07 09:23:16 our-app:         at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1222)
Jul 07 09:23:16 our-app:         at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)
Jul 07 09:23:16 our-app:         at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
Jul 07 09:23:16 our-app:         at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
Jul 07 09:23:16 our-app:         at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
Jul 07 09:23:16 our-app:         at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
Jul 07 09:23:16 our-app:         at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
Jul 07 09:23:16 our-app:         at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:955)
Jul 07 09:23:16 our-app:         at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918)
Jul 07 09:23:16 our-app:         at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583)
Jul 07 09:23:16 our-app:         at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:734)
Jul 07 09:23:16 our-app:         at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:408)
Jul 07 09:23:16 our-app:         at org.springframework.boot.SpringApplication.run(SpringApplication.java:308)
Jul 07 09:23:16 our-app:         at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:164)
...
Jul 07 09:23:16 our-app: Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springdoc.core.providers.ObjectMapperProvider' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
Jul 07 09:23:16 our-app:         at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1801)
Jul 07 09:23:16 our-app:         at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1357)
Jul 07 09:23:16 our-app:         at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1311)
Jul 07 09:23:16 our-app:         at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887)
Jul 07 09:23:16 our-app:         at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791)
Jul 07 09:23:16 our-app:         ... 39 more

We traced the issue to a mismatching auto configuration @Condition, where org.springdoc.kotlin.SpringDocKotlinConfiguration (in springdoc-openapi-kotlin) is instantiated whenever springdoc-openapi is enabled, however it's constructor parameter depdendency org.springdoc.core.providers.ObjectMapperProvider is instantiated by org.springdoc.core.SpringDocConfiguration (in springdoc-openapi-common) which itself gets only instantiated in a web application context (@ConditionalOnWebApplication).

To Reproduce

Using Kotlin 1.6.20, Spring Boot 2.6.9 and springdoc-openapi 1.6.9, build a minimal Spring Boot application that explicitly sets WebApplicationType.NONE. Put springdoc-openapi-kotlin on the class path and attempt to start the application.

Expected behavior

Application start-up should not be hindered by having springdoc-openapi modules on the class path, even if the application is not a web app. We would either expect org.springdoc.kotlin.SpringDocKotlinConfiguration being only applied in web applications, or alternatively have the org.springdoc.core.providers.ObjectMapperProvider available regardless of web application type.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions