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

Maven构建在Surefire测试Test50后挂起问题求助

解决DB Surefire测试在Test50后挂起的问题

先梳理下你的问题背景:无代码变更,DB测试跑完Test50后就挂住了,Test51完全没启动;不管是用mvndebug -DforkCount=0 clean install还是普通的mvn clean install都出问题;换过Maven版本、Surefire插件版本和fork配置都没用,只有特定的Surefire配置组合能正常跑。结合你提供的线程dump和环境信息,我来帮你分析下原因和解决方案。

你的可用Surefire配置

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>2.21.0</version>
  <configuration>
    <forkMode>always</forkMode>
    <forkCount>1</forkCount>
    <reuseForks>true</reuseForks>
    <threadCount>1</threadCount>
    <parallel>suites</parallel>
  </configuration>
</plugin>

线程Dump关键信息拆解

Main线程状态分析

"main@1" prio=5 tid=0x1 nid=NA waiting
java.lang.Thread.State: WAITING
at sun.misc.Unsafe.park(Unsafe.java:-1)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.FutureTask.awaitDone(FutureTask.java:429)
at java.util.concurrent.FutureTask.get(FutureTask.java:191)
at org.apache.maven.plugin.surefire.booterclient.ForkStarter.awaitResultsDone(ForkStarter.java:460)
...

Main线程卡在FutureTask.get()方法上,本质是它在等待Surefire启动的Fork测试进程返回完成信号,但这个Fork进程始终没发送信号,导致主线程无限等待。

后台Thread-17状态分析

"Thread-17@5301" daemon prio=5 tid=0x37 nid=NA runnable
java.lang.Thread.State: RUNNABLE
at java.io.FileInputStream.readBytes(FileInputStream.java:-1)
at java.io.FileInputStream.read(FileInputStream.java:255)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:284)
at java.io.BufferedInputStream.read(BufferedInputStream.java:345)
- locked <0x14bb> (a java.io.BufferedInputStream)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
- locked <0x14bc> (a java.io.InputStreamReader)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
...

这个守护线程卡在读取输入流的操作上,结合你使用的Windows 10环境,基本可以确定是Fork进程的stdout/stderr缓冲区被占满,导致进程阻塞,无法向主线程发送完成信号——Windows系统对进程间流的处理逻辑和Unix不同,缓冲区满后会直接阻塞进程,不会自动扩容或处理。

针对性解决方案

1. 重定向测试输出到文件,解决流阻塞

这是最直接的修复方式,在你的可用Surefire配置中添加一行<redirectTestOutputToFile>true</redirectTestOutputToFile>,将测试输出写入文件,避免占满进程间的流缓冲区:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>2.21.0</version>
  <configuration>
    <forkMode>always</forkMode>
    <forkCount>1</forkCount>
    <reuseForks>true</reuseForks>
    <threadCount>1</threadCount>
    <parallel>suites</parallel>
    <redirectTestOutputToFile>true</redirectTestOutputToFile>
  </configuration>
</plugin>

2. 检查Test50的数据库连接是否正确关闭

另一种可能是Test50执行完毕后,数据库连接未彻底关闭,导致Fork进程无法正常退出。你需要检查Test50的代码:

  • 确保所有Connection、Statement、ResultSet都在finally块中关闭,或使用try-with-resources语法自动关闭:
try (Connection conn = getDbConnection()) {
    // 执行数据库操作
} catch (SQLException e) {
    // 异常处理逻辑
}
  • 也可以查看MySQL连接池状态,确认是否有未释放的连接占用资源。

3. 升级Surefire版本,规避旧版本Windows兼容bug

你当前使用的Surefire 2.21.0是较老版本,在Windows的fork机制上可能存在已知bug。尝试升级到3.0.0及以上的稳定版本,同时禁用进程复用(避免资源泄漏):

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>3.0.0-M7</version>
  <configuration>
    <forkCount>1</forkCount>
    <reuseForks>false</reuseForks>
    <redirectTestOutputToFile>true</redirectTestOutputToFile>
  </configuration>
</plugin>

4. 排查Windows文件句柄泄漏

如果测试中涉及大量文件操作,可能导致文件句柄泄漏,进而阻塞流读取。可以通过Windows任务管理器查看进程的句柄数,确认是否有异常增长;同时检查测试代码中的文件流,确保所有流都已正确关闭。


内容的提问来源于stack exchange,提问作者Paul C. R.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:39:31