I'm trying to get Swagger UI to work in my project and I'm following these docs, but whatever I try my application instantly crashes with the following exception:
Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'securityConfig': Unsatisfied dependency expressed through method 'setContentNegotationStrategy' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration$EnableWebMvcConfiguration': Unsatisfied dependency expressed through method 'setConfigurers' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'swaggerWebMvcConfigurer' defined in class path resource [org/springdoc/webmvc/ui/SwaggerConfig.class]: Unsatisfied dependency expressed through method 'swaggerWebMvcConfigurer' parameter 1; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'indexPageTransformer' defined in class path resource [org/springdoc/webmvc/ui/SwaggerConfig.class]: Unsatisfied dependency expressed through method 'indexPageTransformer' parameter 3; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'swaggerWelcome' defined in class path resource [org/springdoc/webmvc/ui/SwaggerConfig.class]: Post-processing of merged bean definition failed; nested exception is java.lang.IllegalStateException: Failed to introspect Class [org.springdoc.webmvc.ui.SwaggerWelcomeWebMvc] from ClassLoader [jdk.internal.loader.ClassLoaders$AppClassLoader@251a69d7]
I'm using Kotlin with Spring Boot and these are my Gradle dependencies:
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework.boot:spring-boot-starter-jooq")
implementation("org.springframework.boot:spring-boot-starter-security")
implementation("org.springframework.boot:spring-boot-configuration-processor")
implementation("org.springframework.boot:spring-boot-starter-validation")
implementation("org.springframework.boot:spring-boot-starter-log4j2")
implementation("com.braintreepayments.gateway:braintree-java:3.14.0")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.13.1")
implementation("com.fasterxml.jackson.core:jackson-databind:2.13.2")
implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.13.2")
implementation("org.apache.logging.log4j:log4j-layout-template-json")
implementation("org.springdoc:springdoc-openapi-kotlin:1.6.6")
implementation("org.springdoc:springdoc-openapi-ui:1.6.6")
implementation("org.jooq:jooq-meta")
implementation("org.jooq:jooq-kotlin")
implementation("org.jooq:jooq-codegen")
implementation("org.jooq:jooq-codegen-maven")
implementation("org.jooq:jooq-meta-extensions")
implementation("org.jetbrains.kotlin:kotlin-reflect:1.6.10")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.10")
implementation("com.zaxxer:HikariCP:5.0.1")
implementation("com.github.ben-manes.caffeine:caffeine:3.0.5")
implementation("org.flywaydb:flyway-core:8.5.4")
implementation("org.postgresql:postgresql:42.3.3")
I've tried a lot of different packages in a lot of different combinations, but it will always throw an exception at startup.
Plugins section of Gradle file:
plugins {
id("org.springframework.boot") version "3.0.0-SNAPSHOT"
id("io.spring.dependency-management") version "1.0.11.RELEASE"
id("org.flywaydb.flyway") version "8.5.4"
id("nu.studer.jooq") version "7.1.1"
kotlin("jvm") version "1.6.20-RC"
kotlin("plugin.spring") version "1.6.20-RC"
}
Spring Boot 3 will use Jakarta EE while Spring Boot 2 still uses Java EE. This move includes a namespace change for the Servlet API from javax.servlet
to jakarta.servlet
. Your application fails because Springdoc 1.x tries to load classes from the old namespace but Spring Boot 3 only pulls in the new namespace.
Springdoc has released a milestone release that works with Jakarta EE and the milestone releases of Spring Boot 3: https://github.com/springdoc/springdoc-openapi/issues/1284
In a Java application, you can replace
implementation 'org.springdoc:springdoc-openapi-ui:1.6.6'
with
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.0-M1'
There is also an official Maven example here: https://github.com/springdoc/springdoc-openapi-demos/tree/2.x/demo-spring-boot-3-webmvc
If you only include the starter into a Kotlin project with
implementation("org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.0-M1")
this seems to work fine and generates the Swagger UI. But it seems there is currently no corresponding milestone release for springdoc-openapi-kotlin
.