Method not found: is$jacocoData

问题发现:

       LZ 因为排查问题,通过跳板机登录到测试环境的服务器,偶然发现在 user 服务的错误日志里面,出现如下报错:

java.beans.IntrospectionException: Method not found: is$jacocoData
    at java.beans.PropertyDescriptor.<init>(PropertyDescriptor.java:107)
    at java.beans.PropertyDescriptor.<init>(PropertyDescriptor.java:71)
    at com.xxx.user.service.impl.UserService.fieldsLog(UserService.java:309)
    at com.xxx.user.service.impl.UserService.lambda$log$127(UserService.java:292)
    at com.alibaba.ttl.TtlRunnable.run(TtlRunnable.java:51)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

问题排查:

       LZ 通过堆栈日志定位到具体的代码,然后本地 debug,并没有复现该问题。有此排除不是代码本身的问题,然后到网上搜索相关的资料发现该报错是 jacoco 引起的,而 jacoco 是用来统计单元测试的代码覆盖率的。然后排查代码也没有引入相关的依赖,马上排查 user 服务的启动参数,发现确实是通过 javaagent 技术引入的依赖:

root     31787     1  0  2020 ?        02:56:19 java -jar -javaagent:/root/.ci_coverage/jacocoagent.jar=includes=com.user.*,output=tcpserver,port=30041,address=x.x.x.x

为了验证确实是该依赖引起的问题,LZ 下载该 jar 包,在 Idea VM 添加如下参数:

-javaagent:/Users/xxxx(你的jar包目录)/jacocoagent.jar=output=tcpserver,address=127.0.0.1,port=10086  

然后在报错代码处进行 debug 发现在 Fileds 那块多出一个字段 User.$jacocoData,在 User 对象中是没有这个字段的,所以报 Method not found: is$jacocoData 错误。至此,困扰 LZ 的这个问题找到了根源。

问题分析:

       为什么反射之后会多出来一个 $jacocoData 字段呢,那是因为 jacoco 执行单元测试的代码覆盖率时,会在被测类中添加两个成员:私有静态字段 $ jacocoData 和私有静态方法 $ jacocoInit(), 两个成员都被标记为合成的。

问题解决:

       既然 jacoco 执行单元测试的代码覆盖率时,会将多出的成员标记为合成的,那我们只需要在代码中忽略合成成员就行。

参考文档:

       https://github.com/jacoco/jacoco/issues/168

       https://www.eclemma.org/jacoco/trunk/doc/faq.html

发布了67 篇原创文章 · 获赞 64 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/jack1liu/article/details/103916788