Springdoc 2.8.15与Spring Boot 3.5.11兼容问题:使用@Parameter或@OpenApiDefinition注解时触发NoSuchMethodError错误
问题描述
我在组合使用Springdoc 2.8.15和Spring Boot 3.5.11时碰到了一个棘手的问题:当不使用@Parameter或@OpenApiDefinition注解时,API文档规格能正常生成;但只要用上其中任意一个注解,就会抛出如下错误:
{"code":"SERVLET","message":"Handler dispatch failed: java.lang.NoSuchMethodError: 'io.swagger.v3.oas.annotations.media.Schema$RequiredMode io.swagger.v3.oas.annotations.media.Schema.requiredMode()'"}
我的Gradle配置如下:
plugins { java idea jacoco id("org.springframework.boot") version "3.5.11" id("io.spring.dependency-management") version "1.1.7" } dependencies { implementation("org.springframework.boot:spring-boot-starter-actuator") implementation("org.springframework.boot:spring-boot-starter-web") implementation("org.springframework.kafka:spring-kafka") implementation("org.springframework.boot:spring-boot-starter-validation") implementation("org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.15") }
API接口定义示例:
@Tag( name = "Frequency API", description = "Controls the frequency of the simulation" ) @RequestMapping("/api/v1/frequency") public interface FrequencyApi { /** * Set the frequency of the simulation. A value of 0 means the simulation stops. * * @param frequency The frequency to set (0 <= frequency <= 100_000) */ @Operation( summary = "Set the simulation frequency", description = "Sets the frequency for the simulation. A value of 0 means the simulation stops. Max value is 100.000" ) @PutMapping("/{frequency}") @ResponseStatus(code = NO_CONTENT) void putFrequency( @Parameter(description = "The frequency to be set", required = true, example = "10") @Min(0) @Max(100_000) @PathVariable("frequency") int frequency ); }
问题原因
这个错误的本质是依赖版本冲突:io.swagger.v3.oas.annotations.media.Schema类的requiredMode()方法在某个依赖版本中不存在。Spring Boot 3.5.11的依赖管理机制可能引入了较低版本的OpenAPI注解库(如swagger-annotations或openapi-annotations),而Springdoc 2.8.15需要的是更高版本的注解库,二者版本不兼容就导致了方法找不到的报错。
解决方案
以下是几种可以快速解决这个问题的方法:
1. 使用Springdoc的BOM统一管理依赖版本
Springdoc提供了BOM(物料清单)来确保所有相关依赖版本完全一致,从根源避免冲突。在Gradle的dependencyManagement块中引入Springdoc的BOM即可:
dependencyManagement { imports { mavenBom "org.springdoc:springdoc-openapi-bom:2.8.15" } }
这样会强制项目中所有Springdoc相关依赖(包括底层的注解库)使用2.8.15对应的版本,和你引入的Springdoc starter版本保持严格一致。
2. 显式指定OpenAPI注解库的版本
如果不想使用BOM,也可以直接在依赖中显式引入正确版本的OpenAPI注解库,同时排除Springdoc starter中自带的可能冲突的版本:
dependencies { // 其他依赖保持不变... implementation("org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.15") { exclude group: "io.swagger.core.v3", module: "swagger-annotations" exclude group: "io.swagger.core.v3", module: "openapi-annotations" } // 引入与Springdoc 2.8.15匹配的注解版本 implementation "io.swagger.core.v3:swagger-annotations:2.2.20" implementation "io.swagger.core.v3:openapi-annotations:2.2.20" }
3. 检查并排除冲突的依赖
先运行Gradle命令查看完整依赖树,定位到底是哪个依赖引入了冲突的旧版本注解库:
./gradlew dependencies --configuration runtimeClasspath | grep -A5 -B5 "swagger-annotations"
从输出结果中找到冲突的来源后,在对应的依赖上直接排除冲突的模块即可。
验证解决效果
修改完依赖配置后,重新构建项目并启动应用,尝试访问Swagger UI(默认地址为http://localhost:8080/swagger-ui.html),如果API文档能正常加载且没有报错,就说明问题已经解决了。
备注:内容来源于stack exchange,提问作者Thomas




