You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot测试环境无法创建应用上下文问题求助

问题背景

  • 基于Spring Boot 2.6.6开发无数据库的REST中间层应用,正常启动无异常,但执行测试套件时无法创建应用上下文
  • 初始报错:java.lang.StackOverflowError,栈信息重复ch.qos.logback.classic.spi.ThrowableProxy.<init>
  • 定位到问题源于一个基于Spring Boot 2.1.6.RELEASE的权限认证Maven依赖(使用AOP)
  • 关闭Logback后出现java.lang.IllegalStateException: Failed to unwrap proxied object异常
  • 开启Debug日志后触发javax.validation.NoProviderFoundException,提示缺少Jakarta Bean Validation提供者,添加hibernate-validator和spring-boot-starter-validator依赖无效
  • 已尝试的无效方案:调整@SpringBootTest配置、更换AOP依赖、启用@EnableAspectJAutoProxy、代理解包方案

解决方案

1. 正确配置Hibernate Validator解决NoProviderFoundException

Spring Boot 2.6.x依赖Jakarta Bean Validation 2.0+(对应Hibernate Validator 6.x),而旧版Spring Boot 2.1.x依赖Java EE体系的Bean Validation,跨版本依赖冲突会导致提供者无法加载,按以下步骤处理:

  • 排除冲突依赖:在权限认证依赖中排除旧版validation相关依赖,避免与Spring Boot 2.6.x的依赖冲突:
    <dependency>
        <groupId>你的权限认证依赖groupId</groupId>
        <artifactId>你的权限认证依赖artifactId</artifactId>
        <version>对应版本</version>
        <exclusions>
            <exclusion>
                <groupId>javax.validation</groupId>
                <artifactId>validation-api</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.hibernate.validator</groupId>
                <artifactId>hibernate-validator</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    
  • 引入兼容的官方starter:添加Spring Boot官方的validation starter,版本由Spring Boot parent自动管理,确保兼容性:
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-validation</artifactId>
    </dependency>
    
  • 强制锁定API版本:如果仍存在依赖冲突,在dependencyManagement中明确指定Jakarta版本的validation-api:
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>jakarta.validation</groupId>
                <artifactId>jakarta.validation-api</artifactId>
                <version>2.0.2</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
    
  • 验证类路径:执行mvn dependency:tree命令检查,确保类路径中只有jakarta.validation:jakarta.validation-api和org.hibernate.validator:hibernate-validator,无旧版javax.validation:validation-api。

2. 栈溢出与代理解包异常的整体解决方案

解决Logback栈溢出问题

该问题是异常被AOP代理反复捕获包装,导致Logback生成ThrowableProxy时递归调用,处理方式:

  • 调整AOP切面逻辑:检查权限认证AOP的@Around或@AfterThrowing通知,避免对异常进行重复包装,确保异常仅被处理一次。
  • 限制Logback异常栈深度:在logback-spring.xml中配置异常栈打印的最大深度,避免递归解析:
    <configuration>
        <!-- 其他配置 -->
        <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
            <encoder>
                <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n%ex{5}</pattern>
                <!-- %ex{5} 限制仅打印5层异常栈 -->
            </encoder>
        </appender>
    </configuration>
    

解决代理解包异常

Failed to unwrap proxied object是跨Spring版本的代理类不兼容导致,处理方式:

  • 强制使用CGLIB代理并暴露代理:在启动类添加@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true),使用CGLIB代理替代JDK动态代理,同时允许Spring暴露代理对象。
  • 精简测试上下文:在@SpringBootTest中排除权限认证相关的自动配置类,减少测试时加载的Bean:
    @SpringBootTest(exclude = {AuthAutoConfiguration.class})
    public class YourTestClass {
        // 测试代码
    }
    
  • 升级权限认证依赖版本:如果可行,将权限认证依赖升级到与Spring Boot 2.6.x兼容的版本(建议2.5.x及以上),从根源解决跨版本的代理、依赖冲突问题。

内容的提问来源于stack exchange,提问作者BT_Code

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 21:35:23