为什么 Gradle + Jacoco 抛出与 JAXB 类 有关的异常?

Why does Gradle + Jacoco throw exception pertaining JAXB classes?

我是 Jacoco 的新手,我才刚学会 Gradle。

所以在子项目中我只有:

apply plugin: jacoco

当我 运行 gradle test 我得到:

Caused by: javax.xml.bind.JAXBException: An Error Occurred While Scanning Context Classes!
 - with linked exception:
[java.lang.NoSuchMethodException: Failed to Locate Method for Element, Name = $jacocoData, MethodName = set$jacocoData, Type = class com.someco.components.thing.stuff.Feedback, Argument Type = class [Z]
    at javolution.xml.internal.annotation.JAXBAnnotatedObjectReaderImpl.<init>(JAXBAnnotatedObjectReaderImpl.java:98)
    at javolution.xml.internal.annotation.JAXBAnnotationFactoryImpl.createJAXBAnnotatedObjectReader(JAXBAnnotationFactoryImpl.java:31)
    at com.someco.commons.util.JaxbUtils.unmarshal(JaxbUtils.java:112)
    ... 47 more
Caused by: java.lang.NoSuchMethodException: Failed to Locate Method for Element, Name = $jacocoData, MethodName = set$jacocoData, Type = class com.someco.components.thing.stuff.Feedback, Argument Type = class [Z
    at javolution.xml.internal.annotation.AbstractJAXBAnnotatedObjectParser.getMethodByXmlName(AbstractJAXBAnnotatedObjectParser.java:533)
    at javolution.xml.internal.annotation.AbstractJAXBAnnotatedObjectParser.scanClass(AbstractJAXBAnnotatedObjectParser.java:281)
    at javolution.xml.internal.annotation.AbstractJAXBAnnotatedObjectParser.registerContextClasses(AbstractJAXBAnnotatedObjectParser.java:149)
    at javolution.xml.internal.annotation.AbstractJAXBAnnotatedObjectParser.registerContextClasses(AbstractJAXBAnnotatedObjectParser.java:143)
    at javolution.xml.internal.annotation.AbstractJAXBAnnotatedObjectParser.registerContextClasses(AbstractJAXBAnnotatedObjectParser.java:143)
    at javolution.xml.internal.annotation.JAXBAnnotatedObjectReaderImpl.<init>(JAXBAnnotatedObjectReaderImpl.java:93)
    ... 49 more

我没有适合您的解决方案,但您的代码出现了问题。 Jacoco 动态地将一个字段和一个方法插入到您的 类 中,并使用它们来跟踪覆盖率指标。如果您的代码使用反射,这可能是个问题,因为 jacoco 的字段在反射调用中返回 - 除非您显式过滤掉它们。 Jacoco FAQs 是这样说的:

My code uses reflection. Why does it fail when I execute it with JaCoCo?

To collect execution data JaCoCo instruments the classes under test which adds two members to the classes: A private static field $jacocoData and a private static method $jacocoInit(). Both members are marked as synthetic.

Please change your code to ignore synthetic members. This is a good practice anyways as also the Java compiler creates synthetic members in certain situation.

现在,我对 javolution 知之甚少,我不确定它是否允许在它拾取的字段上应用过滤器,但这就是我开始寻找的地方。

或者,您可以从 jacoco 中排除问题 classes/packages,但需要注意的是您不会测量排除的 classes/packages.

的测试覆盖率

所以你需要 2 个排除项。一个用于汇编,另一个用于报告。要解决这个具体问题,您只需要:

test {
    jacoco {
        excludes = [ "com.stuff.ours.jaxb.stuff.*",
                     "javolution.*"]
    }
}