You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Springdoc 2.8.15与Spring Boot 3.5.11兼容问题:使用@Parameter或@OpenApiDefinition注解时触发NoSuchMethodError错误

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-annotationsopenapi-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

火山引擎 最新活动