美文网首页
代码单测EOF问题解决过程

代码单测EOF问题解决过程

作者: 程序猿皮皮 | 来源:发表于2021-09-27 17:03 被阅读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

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

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

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

    相关文章

      网友评论

          本文标题:代码单测EOF问题解决过程

          本文链接:https://www.haomeiwen.com/subject/ljqknltx.html