2

I'm new to Jacoco and I've only just picked up Gradle.

So in subprojects I have only:

apply plugin: jacoco

When I run gradle test I get:

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
user447607
  • 5,149
  • 13
  • 33
  • 55
  • What is javolution? It apparently uses jaxb and has a problem with the field that jacoco inserts into your code, to track coverage - it seems to be complaining that it cant find a set method for jacoco's private field. – RaGe Apr 22 '16 at 15:02
  • "Javolution is a real-time library aiming to make Java or Java-Like/C++ applications faster and more time predictable. Indeed, time-predictability can easily be ruined by the use of the standard library (lazy initialization, array resizing, etc.) which is not acceptable for safety-critical systems." – user447607 Apr 22 '16 at 15:05
  • Any ideas if I can I exclude generated classes somehow? – user447607 Apr 22 '16 at 15:08
  • I can tell you it's not anywhere in Gradle for this project. In fact until this, I didn't know there was any JAXB in there. There is a lot of JAXB elsewhere though, meaning that we have a lot of generated classes that may or may not have javolution stuff in them. – user447607 Apr 22 '16 at 15:13
  • Maybe this is what I need: http://stackoverflow.com/questions/29887805/filter-jacoco-coverage-reports-with-gradle – user447607 Apr 22 '16 at 15:18

2 Answers2

1

I don't have a solution for you, but here's whast happening with your code. Jacoco dynamically inserts a field and a method into your classes and uses them to track coverage metrics. This can be a problem if your code uses reflection, because jacoco's fields are returned in reflection calls - unless if you explicitly filter them out. Jacoco FAQs says this:

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.

Now, knowing very little about javolution, I'm not sure if it allows for applying filters on the fields it is picking up, but that is where I would start looking.

Alternatively you can exclude problem classes/packages from jacoco, with the caveat that you will not be measuring the test coverage for the excluded classes/packages.

Community
  • 1
  • 1
RaGe
  • 22,696
  • 11
  • 72
  • 104
  • So what I'll try is an exclusion for Javolution as mentioned here: http://stackoverflow.com/questions/29887805/filter-jacoco-coverage-reports-with-gradle and I should anticipate further exclusions for my generated classes. – user447607 Apr 22 '16 at 15:26
  • OK, the problem there was that you need 2 sets of excludes, one is for the report and the other is for compilation, I assume. – user447607 Apr 25 '16 at 15:42
0

So you need 2 excludes. One is for compilation and the other is for the reports. To solve this specific problem, all you need is:

test {
    jacoco {
        excludes = [ "com.stuff.ours.jaxb.stuff.*",
                     "javolution.*"]
    }
}
user447607
  • 5,149
  • 13
  • 33
  • 55