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

时间:2016-04-22 14:42:47

标签: gradle jaxb jacoco

我是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

2 个答案:

答案 0 :(得分:1)

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

  

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

     

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

     

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

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

或者,您可以从jacoco中排除问题类/包,但需要注意的是,您不会测量排除的类/包的测试范围。

答案 1 :(得分:0)

所以你需要2个排除。一个是编译,另一个是报告。要解决这个特定问题,您只需要:

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