Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
l61ronny opened this issue Jul 7, 2022 · 1 comment

Comments

@l61ronny
Copy link

l61ronny commented Jul 7, 2022

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.

@kiss90benedek
Copy link

Thank you for reporting this.
In SpringDocConfiguration.java you also have the annotation @ConditionalOnProperty(name = SPRINGDOC_ENABLED, matchIfMissing = true)
I was able to fix this issue by setting the config springdoc.api-docs.enabled to false.

bnasslahsen pushed a commit that referenced this issue Jul 31, 2022
shayany added a commit to navikt/etterlevelse that referenced this issue May 23, 2023
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

No branches or pull requests

2 participants