返回

修复 Spring Boot 3 与 Springdoc 版本冲突: `SwaggerConfig` 报错

java

搞定 Spring Boot 3.0 与 Springdoc 集成报错:Error processing condition on org.springdoc.webmvc.ui.SwaggerConfig.indexPageTransformer

刚把项目升级到 Spring Boot 3.0(还是个 SNAPSHOT 版本),寻思着加上 springdoc-openapi-ui 来生成个 API 文档,方便前后端对接。结果依赖一加,项目直接撂挑子不干了,启动时抛出 Error processing condition on org.springdoc.webmvc.ui.SwaggerConfig.indexPageTransformer 这个错误。看样子是版本冲突或者不兼容,但具体是哪个版本没对上,或者该用哪个版本,一时半会儿还真有点懵。

下面是相关的 pom.xml 配置和启动类:

<!-- pom.xml 父依赖 -->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.0.0-SNAPSHOT</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<!-- pom.xml 相关依赖 -->
<dependency>
   <groupId>org.springdoc</groupId>
   <artifactId>springdoc-openapi-ui</artifactId>
   <!-- 注意:这里没有指定版本! -->
</dependency>

<!-- 之前可能尝试过的swagger依赖 (已注释) -->
<!-- <dependency>-->
<!--   <groupId>io.swagger</groupId>-->
<!--   <artifactId>swagger-annotations</artifactId>-->
<!--   <version>${swagger.annotations.version}</version>-->
<!--  </dependency>-->
// 主启动类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class MbblueprintbackendApplication {

    public static void main(String[] args) {
        SpringApplication.run(MbblueprintbackendApplication.class, args);
    }

}

启动时的报错截图大概长这样(虽然你提供的是链接,我们假定它显示了上面提到的错误栈信息):
Error Stack Trace Example

遇到这问题别慌,这通常是 Spring Boot 版本和 Springdoc-OpenAPI 版本没“配对成功”导致的。咱们来分析下为啥会这样,再看看怎么解决。

为啥会这样?原因分析

这个问题的根源,大概率是 版本不兼容 ,特别是 Spring Boot 3.0 带来的变化和 springdoc-openapi 库之间的版本匹配问题。具体点说,有几个可能的原因:

  1. Spring Boot 3.0 的大改动 :Spring Boot 从 3.0 版本开始,做了一些重要的底层调整:
    • 基线提升 :要求 Java 17 作为最低版本。
    • 迁移到 Jakarta EE 9+ :这是一个重大的变化。以前 Java EE 的 API 包名是 javax.*,现在 Jakarta EE 的 API 包名变成了 jakarta.*。这意味着很多依赖库,包括 Spring Framework 6(Spring Boot 3.0 的基础)本身以及许多第三方库,都需要更新其代码以使用新的 jakarta.* 包。
  2. Springdoc-OpenAPI 的适配springdoc-openapi 这个库是专门用来集成 OpenAPI 3 (以前叫 Swagger) 规范到 Spring Boot 应用的。它需要紧密地与 Spring Boot 和 Spring Web MVC (或 WebFlux) 的内部机制配合工作。当 Spring Boot 进行了像迁移到 Jakarta EE 这样的大改动后,springdoc-openapi 也必须发布相应的版本来适配这些改动。如果使用的 springdoc-openapi 版本是为 Spring Boot 2.x(使用 javax.* 包)构建的,那么它在 Spring Boot 3.0 的环境下自然会“水土不服”,导致各种配置或 Bean 初始化失败。错误信息中的 SwaggerConfig.indexPageTransformer 正是 springdoc 内部处理 Swagger UI 页面相关的 Bean,它在处理条件化配置 (@Conditional...) 时出错了,这强烈暗示了底层环境(比如所需的类或配置属性)与预期不符。
  3. Maven 依赖版本管理机制 :在你的 pom.xml 文件里,给 springdoc-openapi-ui 这个依赖只写了 groupIdartifactId没有明确指定 <version>
    <dependency>
       <groupId>org.springdoc</groupId>
       <artifactId>springdoc-openapi-ui</artifactId>
       <!-- <version>???</version>  <-- 这里是空的 -->
    </dependency>
    
    在这种情况下,Maven 会怎么做?它通常会尝试解析最新的 稳定 (stable) 发行版本。问题来了,你用的 Spring Boot 是 3.0.0-SNAPSHOT,这是一个 快照 (snapshot) 版本,非常新,甚至是开发中的版本。而 Maven 拉取的那个最新的 springdoc-openapi-ui 稳定版,很可能是针对当时最新的 Spring Boot 稳定版 (比如 Spring Boot 2.7.x 或早期的 3.0.x 正式版)构建的,它并不保证与一个不稳定的 SNAPSHOT 版 Spring Boot 完全兼容。特别是,早期的 Springdoc 版本不支持 Spring Boot 3 的 Jakarta EE 迁移。
  4. SNAPSHOT 版本的不确定性 :使用 SNAPSHOT 版本的 Spring Boot 本身就带来了不稳定性。SNAPSHOT 版本是开发过程中的构建,可能包含未完成的功能、Bug 或者 API 的频繁变动。依赖库的开发者通常会等 Spring Boot 发布了里程碑(Milestone)或正式版(Release)之后,再发布与之兼容的库版本。所以,用 SNAPSHOT 版 Spring Boot 时,找到完全兼容的第三方库版本有时需要更仔细的查找,甚至可能需要使用同样处于 SNAPSHOT 阶段的第三方库(如果提供的话)。

小结一下 :你遇到的问题,核心在于 Spring Boot 3.0.0-SNAPSHOT 的新特性(特别是 Jakarta EE 的包名变更)与你隐式引入的、很可能基于旧版 Spring Boot (或 javax.* 包) 构建的 springdoc-openapi-ui 稳定版之间存在冲突。

怎么办?解决方案来了

既然知道了问题所在,解决起来就有方向了。主要是确保 Spring Boot 和 Springdoc-OpenAPI 的版本能够正确匹配。

方案一:明确指定兼容的 Springdoc 版本 (推荐)

这是最直接有效的办法。你需要找到一个明确支持 Spring Boot 3.0(以及 Jakarta EE)的 springdoc-openapi 版本,并在 pom.xml 中显式指定它。

原理:
通过在 <dependency> 标签内添加 <version> 子标签,我们强制 Maven 使用我们指定的版本,而不是让它自己去猜(通常是猜最新的稳定版)。选择的版本必须是官方声明兼容你所使用的 Spring Boot 大版本(这里是 3.0.x)的。

操作步骤:

  1. 查找兼容版本: 查阅 springdoc-openapi 官方文档或其 GitHub Release Notes,找到哪个版本开始支持 Spring Boot 3.x。通常,springdoc-openapi 的版本号会与 Spring Boot 版本有所对应或在文档中明确说明。对于 Spring Boot 3.0,你需要 springdoc-openapi 2.0.0 或更高版本

  2. 修改 pom.xml

    • 推荐使用 starter 依赖 :官方推荐使用 springdoc-openapi-starter-webmvc-ui(针对 Spring Web MVC)或 springdoc-openapi-starter-webflux-ui(针对 Spring WebFlux)。这些 starter 依赖会帮你把核心库 (springdoc-openapi-common) 和 UI 相关的库 (springdoc-openapi-ui) 以及其他必要的传递性依赖都管理好。你的项目看起来是 Web MVC 项目,所以用前者。
    • 添加版本号 :假设我们选择 2.1.0 版本(这是一个兼容 Spring Boot 3.x 的较新稳定版,你可以根据需要选择更新的版本,如 2.5.0 等)。

    修改你的 pom.xml 文件,将之前的依赖替换或修改为:

    <dependency>
        <groupId>org.springdoc</groupId>
        <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
        <version>2.1.0</version> <!-- 或者更新的兼容版本, 例如 2.5.0 -->
    </dependency>
    

    注意: 务必将 <version> 标签中的版本号替换为你查找到的、确认与 Spring Boot 3.0 兼容的最新稳定版本。可以参考 Springdoc 官方网站 的文档。

  3. 清理和重新构建项目:
    在修改 pom.xml 后,最好执行 Maven 清理和重新构建命令,确保旧的、不兼容的依赖被移除,新的依赖被正确下载和使用。

    mvn clean install -U
    

    或者在你的 IDE(如 IntelliJ IDEA)中刷新 Maven 项目。 -U 参数会强制更新 SNAPSHOT 依赖和发布依赖。

进阶使用技巧 / 建议:

  • 统一管理依赖版本 :在一个稍大点的项目中,推荐使用 pom.xml<dependencyManagement> 部分来统一管理所有重要依赖的版本。这样可以避免在多个地方重复声明版本号,也更容易追踪和升级。

    <properties>
        <springdoc-openapi.version>2.1.0</springdoc-openapi.version> <!-- 定义版本属性 -->
    </properties>
    
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springdoc</groupId>
                <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
                <version>${springdoc-openapi.version}</version>
            </dependency>
            <!-- 其他需要统一管理的依赖 -->
        </dependencies>
    </dependencyManagement>
    
    <dependencies>
        <dependency>
            <groupId>org.springdoc</groupId>
            <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
            <!-- 这里不需要再写 version 了 -->
        </dependency>
        <!-- 其他项目依赖 -->
    </dependencies>
    

方案二:将 Spring Boot 从 SNAPSHOT 版切换到稳定版

如果你不是非得用 Spring Boot 的最新开发快照不可,切换到一个稳定的 Spring Boot 3.x 发行版(比如 3.0.1, 3.1.5, 3.2.0 等)通常是更明智的选择。

原理:
稳定版(Release)的 Spring Boot 经过了更充分的测试,API 相对固定。大多数第三方库(如 springdoc-openapi)会优先确保与这些稳定版兼容。当你使用稳定版 Spring Boot 时,即使不显式指定 springdoc 的版本,Maven 自动拉取的最新稳定版 springdoc 也更有可能与之兼容(尤其是当你使用的 Spring Boot 版本已经发布了一段时间后)。

操作步骤:

  1. 修改 pom.xml 父依赖:
    找到 <parent> 部分,将其中的 version3.0.0-SNAPSHOT 改为一个已发布的稳定版本。例如,改为 3.0.12 (Spring Boot 3.0.x 系列的最后一个维护版本) 或者更新的 3.1.x, 3.2.x 系列。

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <!-- <version>3.0.0-SNAPSHOT</version> --> <!-- 注释掉或删除这行 -->
        <version>3.1.5</version>  <!-- 使用一个稳定的版本 -->
        <relativePath/>
    </parent>
    

    选择哪个稳定版取决于你的项目需求和对新特性的要求。建议选择较新的维护版本以获得最新的 Bug 修复和安全更新。

  2. 调整 springdoc-openapi 依赖(可选但推荐):
    即使切换到了稳定版 Spring Boot,为了保险起见,仍然推荐按照 方案一 中的方法,明确指定一个与你选择的 Spring Boot 稳定版兼容的 springdoc-openapi-starter-webmvc-ui 版本。查阅 Springdoc 文档确认兼容性。例如,对于 Spring Boot 3.1.x,springdoc-openapi 版本 2.1.0 或更高版本通常是合适的。

  3. 清理和重新构建项目:
    同样,执行 mvn clean install -U 或在 IDE 中刷新 Maven 项目。

安全建议/开发实践:

  • 避免在生产环境或重要开发中使用 SNAPSHOT 版本 :除非你是在为 Spring Boot 或相关库做贡献,或者确实需要某个只在 SNAPSHOT 中存在的特性,并且愿意承担不稳定的风险,否则尽量使用 Milestone (M) 或 Release Candidate (RC) 或正式 Release 版本。
  • 查阅迁移指南 :如果你是从 Spring Boot 2.x 升级到 3.x,务必阅读 Spring Boot 3.0 的官方迁移指南。里面提到了很多重要的变化点,包括 Jakarta EE 迁移、配置属性变更等,能帮你避免很多坑。

方案三:检查和清理本地 Maven 缓存

虽然概率不高,但有时本地 Maven 仓库 (.m2 目录) 中的缓存可能出现问题,比如下载的 jar 文件损坏,或者存在冲突的旧版本依赖没有被正确清理。

原理:
Maven 会将下载的依赖库存储在本地仓库中以备后用。如果这个缓存出了问题,可能会导致构建或运行时错误。强制更新和清理缓存可以解决这类问题。

操作步骤:

  1. 强制更新依赖: 运行 Maven 命令时加上 -U 参数,强制检查远程仓库的更新(特别是对于 SNAPSHOT 依赖)。
    mvn clean install -U
    
  2. 清理本地仓库中特定依赖: 你可以手动删除本地 Maven 仓库 (~/.m2/repository/) 中 org/springdoc 和可能相关的 Spring Boot 3.0 的目录,然后重新运行 Maven 构建。
  3. 终极手段:删除整个本地仓库(谨慎操作!): 如果怀疑整个缓存有问题,可以备份后删除 ~/.m2/repository 目录。下次构建时,Maven 会重新下载所有需要的依赖。这会比较耗时。
    警告: 删除整个仓库意味着所有项目的依赖都需要重新下载。

什么时候考虑这个方案?
如果方案一和方案二都尝试了,并且确认 pom.xml 配置无误、版本兼容,但问题依旧存在,可以试试清理缓存。

总结一下思路

遇到 Spring Boot 3 与 springdoc-openapi 集成时的 Error processing condition on ...SwaggerConfig... 错误,八九不离十是版本没对上。关键在于:

  • Spring Boot 3.0 是个大版本,带来了 Jakarta EE 等变化,要求依赖库也得跟上。
  • springdoc-openapi 需要特定版本才能支持 Spring Boot 3.x。
  • 直接在 pom.xml 里给 springdoc-openapi-starter-webmvc-ui (或其他 starter) 指定一个已知兼容的 版本号 (比如 2.0.0+ for SB 3.0, 推荐查阅最新文档选型) 是最常见的解法。
  • 尽量避免使用 Spring Boot 的 SNAPSHOT 版本,除非真的需要。切换到稳定版能减少很多不必要的麻烦。
  • 养成查阅官方文档,特别是版本兼容性说明和迁移指南的好习惯,能帮你少走很多弯路。

通过以上步骤,你应该能够解决 springdoc-openapi-ui 在 Spring Boot 3.0 (尤其是 SNAPSHOT 版本) 环境下引起的启动报错问题,让你的 API 文档顺利跑起来。

相关资源链接 (可选)