IntelliJ IDEA运行带代码覆盖率测试触发ClassFormatError如何修复
JMockit+JaCoCo覆盖率执行ClassFormatError修复方案
该错误的核心是JMockit与JaCoCo的字节码增强逻辑冲突。两者都基于Java Instrumentation机制修改目标类的字节码,执行覆盖率统计时JaCoCo会先对类做覆盖率插桩处理,后续JMockit对同一类进行Mock操作时的字节码修改逻辑和已插桩的字节码不兼容,最终触发ClassFormatError。
可用修复方案
调整JMockit加载优先级
确保JMockit的javaagent在JaCoCo之前加载。打开IDEA对应的测试运行配置,在「VM options」栏添加如下参数:
手动指定的agent优先级高于IDEA自动加载的JaCoCo agent,可避免两者的加载顺序冲突。-javaagent:<替换为你本地jmockit.jar的完整路径>修改Mock写法降低字节码修改范围
你当前的写法将BaseValidator.class传入了Expectations构造参数,会触发JMockit重写整个类的字节码,冲突概率更高。改用如下部分Mock的写法,仅针对指定方法做字节码修改:
无需将被测类传入Expectations构造参数,即可实现对目标静态方法的Mock,同时大幅降低字节码修改的范围,减少和JaCoCo插桩的冲突概率。new Expectations() { { BaseValidator.isExistAirLineByTwoCode(anyString); returns(false, true); } };升级相关依赖版本
该类兼容问题在高版本组件中已经做了适配,可尝试做如下升级:- JMockit升级到1.49及以上版本
- JaCoCo升级到0.8.7及以上版本
- IntelliJ IDEA升级到2021.1及以上版本(老版本IDEA内置的JaCoCo版本较低,更容易出现兼容问题)
切换为JaCoCo离线插桩模式
若以上方案都无法适配你的项目环境,可以将JaCoCo改为离线插桩模式,在编译阶段就完成覆盖率插桩,运行测试时不需要加载JaCoCo agent,从根源上避免和JMockit的运行时字节码修改冲突。
内容的提问来源于stack exchange,提问作者poemyong
相关产品推荐
相关产品推荐

