代码单测EOF问题解决过程

2021-09-27  本文已影响0人  程序猿皮皮

代码单测EOF问题解决过程

1. 发现问题

8月16日,应用研发同事反馈,代码提交后执行代码检查时失败,导致代码不能正常合入主干。

正常的流程是:提交代码 -> 执行单测(jacoco-maven)-> 解析单测结果(sonar-jacoco) -> 打包

查看日志,发现是解析单测结果的时候发生EOFException。这个异常表明sonar在读取解析单测结果时发生的问

题,就去排查sonar-jacoco插件的问题。

2. 怀疑sonar

在查找资料的过程发现,jacoco官方最初在旧版本中就是吃掉这个异常的,后面为了更好的暴露问题将EOF异常

抛出。旧版中发生EOF异常sonar会认为单测各种覆盖率等为零。

我于是掉头回去研究要解析的文件内容。正常来讲,执行完单测,jacoco会生成一个jacoco.exec的文件,但是发

现磁盘上这个文件是空的。那么是jacoco-maven在单测环节出问题了?

3. 怀疑jacoco

执行单测的命令时:

阅读jacoco-maven插件相关的文档得知,jacoco是通过JVM的shutdown提供的钩子将单测结果写入磁盘的,而

且是同步的写入的。

在调整提交代码文件的过程中,偶然间发现,这个问题是是偶发的,随机出现的。将代码复制到一个临时文件

夹,重复执行单测命令,发现jacoco.exec时而有内容,时而为空,确定问题是由jacoco引发的。翻查jacoco官方

的issue列表,果然有人遇到同样的问题,jacoco-issue-394,根据大家的讨论得知,问题是由jdk的bug引发的。

在java官方issue中确认了这个问题,一些低版本的jdk中,shutdown主线程会调用钩子线程的join,寄希望于钩

子线程执行完成后在结束主线程,但是如果应用程序中代码主线程调用了interrupt方法的话,会造成关闭指令和

钩子程序形成竞争,如果钩子程序竞争失败,那么文件写入不能完成,jacoco.exec即为空。

项目中全局搜索发现很多单测用例中调用了interrupt方法,再检查我们线上的jdk中ApplicationShutdownHooks

源码,问题确认了!

4. 升级JDK验证

下载最新版本的jdk,重复执行单测命令10次,稳稳的通过。跟团队确认jdk升级流程后将线上4台机器jdk全部升

级,邀请应用研发同事验证多次,编译环节单测均完美通过。

5. 思考

1 mvn org.jacoco:jacoco-maven-plugin:prepare-agent clean test -U

因为以前没人报过类似的问题,所以刚开始以为是提交代码的问题,然后逐个文件筛查,浪费了好多时间。

以后还是要事实求是,根据现场证据科学推断,不要经验主义。

开源组件的官方平台是解决问题的最好的途径,要保持关注,学会使用,善于利用官方提供的资料解决问

上一篇下一篇

猜你喜欢

热点阅读