记一次测试环境因代码覆盖率代理对象jacocoagent引起的NoSuchMethodException

背景

不同环境运行会有不同的效果,生产和开发环境正常,测试环境异常

原因

查看FAT环境JVM信息,有如下配置

1
2
3
-javaagent:/xxx/xxx/jacocoagent.jar=includes=*,output=tcpserver,address=*,port=6300
-javaagent:/xxx/xxx/data/vanda_agent.jar=classpath=/bankapp/deploy/runtime/jar,port=6300,actionType=start,type=1
-javaagent:/xxx/xxx/libra/libra-agent.jar=customDomain

原因是FAT环境中引用了libra做代码覆盖率分析,会用到jacoco-agent.jar代理

JVM通过-javaagent参数指定特定的jar文件启动Instrumentation代理程序,代理程序在状态class文件前会将探针(统计代码)插入到class文件,最后在JVM执行测试代码的过程中完成对覆盖率的分析。jacoco代理收集执行信息并根据请求或在JVM推出时将其转储。

jacoco通过ASM在字节码中插入Probe指针(探测指针),每个探测指针都是一个Boolean变量(true表示执行,false表示没有执行),程序运行时通过改变指针的结果来检测代码的执行情况(不会改变原代码的行为)。

jacoco通过插手字节码的手段进行代码覆盖率的监控,会对字节码进行一定的修改,所以看到的不一定是存在的

插入探针的源码

1
2
boolean[] arrayOfBoolean = $jacocoInit();
arrayOfBoolean[n] = true;

问题分析

因在业务逻辑中是通过反射来便利所有的方法的,便利的时候会便利到探针方法jacocoInit(),当拿着便利的方法去调用的时候,会调用的jacocoInit(),又因为jacoco通过ASM在字节码中插入Probe指针不会改变代码的行为,所以在反射调用的时候会报NoSuchMethodException错

具体可参考:https://www.cnblogs.com/forfreewill/articles/13627983.html


记一次测试环境因代码覆盖率代理对象jacocoagent引起的NoSuchMethodException
http://yoursite.com/post/6cc1f5df.html/
Author
Chase Wang
Posted on
January 5, 2022
Licensed under