Gradle compileTestGroovy抛StackOverflowError 排除依赖仍失败
compileTestGroovy任务触发StackOverflowError的排查方案
核心结论
- 该场景下可基本排除循环依赖作为根因
你已完成两类关键验证:移除全部testImplementation作用域依赖、为剩余测试依赖关闭传递依赖后问题仍存在。循环依赖类栈溢出的本质是编译阶段递归遍历依赖链路触发,只要切断依赖传递路径,递归条件就会消失,和当前的验证结果不匹配。
针对性排查步骤
抓取完整无截断的栈溢出轨迹
你当前贴出的堆栈被省略号截断,Caused by: java.lang.StackOverflowError下方连续重复的递归调用段才是定位根因的核心。执行带全堆栈输出的编译命令,将输出重定向到本地日志文件方便排查:gradle compileTestGroovy --stacktrace --info > build-error.log 2>&1打开生成的日志文件,找到StackOverflowError段下反复出现的同一段方法调用——递归的起点就是问题触发点,常见递归场景包括Groovy编译器在AST转换阶段无限解析类元数据、类路径遍历阶段循环加载同一路径的类。
验证测试代码本身的触发可能性
先临时将src/test/groovy目录下的所有测试代码移出该目录,再执行compileTestGroovy任务:- 如果任务执行成功,说明栈溢出是特定测试代码触发Groovy编译器的已知漏洞(比如Spock 2.0-M5版本处理嵌套闭包、泛型约束的测试用例时,Groovy 3.0早期版本的AST遍历逻辑存在递归缺陷),可通过升级Spock到正式稳定版、匹配对应稳定版Groovy编译器解决
- 如果移空测试代码后任务仍报栈溢出,说明问题来自编译任务的配置层面:检查sourceSets配置是否存在重复添加Groovy源码路径、是否给编译任务的类路径重复挂载了同一套主代码输出,导致编译器循环解析类路径
清理损坏的增量编译缓存
Groovy插件的增量编译索引损坏时,会在递归解析缓存映射的过程中触发栈溢出。直接删除以下目录后重试任务:- 项目根目录下
.gradle文件夹内对应项目的编译缓存 - 项目build目录下的
compileTestGroovy、compiler子目录
- 项目根目录下
调整编译线程的栈容量
如果全栈轨迹显示递归深度不高、只是普通的方法嵌套,大概率是Gradle默认分配的线程栈空间不足。在项目根目录的gradle.properties文件中添加配置:org.gradle.jvmargs=-Xmx2g -Xss4m将编译线程的栈空间从默认1M提升到4M,再执行任务验证。注意:如果是无限递归场景,单纯调大栈空间只能暂时延缓报错,必须找到递归触发点从根源修复。
内容的提问来源于stack exchange,提问作者ThisIsJustAHobby
相关产品推荐
相关产品推荐

