11

当尝试使用 emma:emma 运行 Coverage 或运行 maven 构建时,我得到以下信息:

java.lang.IllegalStateException:无法访问方法:无法将静态最终 [Z 字段 packageName.ClassName.$jacocoData 设置为 [Z

所以我在网上四处搜索,在 EclEmma 网站上找到了以下内容:

我的代码使用反射。为什么当我用 JaCoCo 执行它时它会失败?

为了收集执行数据,JaCoCo 检测了被测试的类,它向类添加了两个成员:一个私有静态字段 $jacocoData 和一个私有静态方法 $jacocoInit()。两个成员都被标记为合成的。

请更改您的代码以忽略合成成员。无论如何,这是一个很好的做法,因为 Java 编译器也会在某些情况下创建合成成员。

但我在网上找不到任何关于如何用 Emma 实际忽略合成成员的文档。

在 STS 中,我在 Preferences/Java/Code Coverage 下查看,我看到一个 Excludes 框来放置排除项(我知道我也可以将排除项放在我的 POM 中)。

我只是想知道需要在那里排除所有合成类。

谢谢

4

2 回答 2

11

我最近使用我正在使用的通用 CSV 导出助手遇到了这个问题。您看到的例外是 Jacoco/Emma 无法设置用于跟踪代码覆盖率的合成字段。您需要允许 Emma 访问该合成字段。

如果您已停止 Emma 访问合成字段,因为添加合成字段会导致您的反射出现问题,例如。您正在使用反射来迭代Field对象集合,只需执行以下操作:

Field[] fields = fooObject.getClass().getDeclaredFields();
Field[] nonSyntheticFields = new Field[fields.length];

for(int i = 0; i < fields.length; i++){         
    if(!fields[i].isSynthetic()){
        nonSyntheticFields[i] = fields[i];
        //Or whatever processing you are doing here with your fields.
    }
}

以上允许您从您在类中声明的字段中分离出您的应用程序不应该真正了解的合成字段。我知道这看起来有点老套,但这是我能想到的最优雅的解决方案。Emma 需要该字段才能检测您的代码,您能做的最好的事情就是确保您的代码不会与该合成变量混淆。

于 2015-03-12T08:43:02.727 回答
1

我认为忽略合成成员的最佳方法如下;

for (Field field : fields) {
    if (!field.isSynthetic()) {
        // enter code here
    }
}
于 2019-01-14T05:14:54.893 回答