Menu

NoClassDefFound test error with Jacoco

Help
2012-03-11
2013-04-24
  • Vincent Massol

    Vincent Massol - 2012-03-11

    Hi guys,

    I'm trying out Jacoco on some maven project. This project builds fine when I don't have Jacoco in the project but as soon as I have it my tests fail with on some third party dep I'm using (PircBotX):


    Caused by: java.lang.ArrayIndexOutOfBoundsException: 0
            at org.pircbotx.hooks.ListenerAdapter.<clinit>(ListenerAdapter.java:106)

    I've checked the source code and line 106 is:

    Class<?> curClass = curMethod.getParameterTypes();

    in:

    static {
    //Map events to methods
    for (Method curMethod : ListenerAdapter.class.getDeclaredMethods()) {
    if (curMethod.getName().equals("onEvent"))
    continue;
    Class<?> curClass = curMethod.getParameterTypes();
    if (!curClass.isInterface()) {
    Set methods = new HashSet();
    methods.add(curMethod);
    eventToMethod.put((Class<? extends Event>) curClass, methods);
    }
    }

    So it seems Jacoco's instrumentation is messing something up but since I don't know what code Jacoco injects I have no clue what the problem can be.

    Any idea?

    Thanks a lot
    -Vincent

     
  • Vincent Massol

    Vincent Massol - 2012-03-11

    Note: Sorry about the title of this issue. I thought the problem was a NoClassDefFoundError initially but I think the root cause is instead this ArrayIndexOutOfBoundsException I reported above.

     
  • Vincent Massol

    Vincent Massol - 2012-03-11

    ok found the problem I think. I was able to see that the method that generates the problem is:

    private static final boolean org.pircbotx.hooks.ListenerAdapter.$jacocoInit()

    So the issue is that the PircBotX project has some code that is not well protected against problems…

    I'll read up to find a way to exclude this class from instrumentation

     
  • Vincent Massol

    Vincent Massol - 2012-03-11

    ok I found it and it works :)

    For the record:

          <plugin>
            <groupId>org.jacoco</groupId>
            <artifactId>jacoco-maven-plugin</artifactId>
            <version>0.5.6.201201232323</version>
            <configuration>
              <destfile>${basedir}/target/coverage-reports/jacoco-unit.exec</destfile>
              <datafile>${basedir}/target/coverage-reports/jacoco-unit.exec</datafile>
              <excludes>
                <exclude>org.pircbotx.hooks.ListenerAdapter</exclude>
              </excludes>
            </configuration>

     
  • Marc R. Hoffmann

    Your analysis is correct. JaCoCo adds two members to instrumented classes:

    - static field $jacocoData
    - static method $jacocoInit

    Both members have the modifiers private and synthetic. So frameworks really shouldn't touch such members.