Jacoco maven plugin clogs up console with Exceptions-java.lang.IllegalStateException: class is already instrumented

Viewed 34831

I am working on sonar code coverage using Jacoco plugin and using power mock mockito combination to write JUnit test cases, while all goes well with the build when I run mvn clean install but the console shows a very very long stack trace chain which keeps coming for many many classes used in the project, and is quite irritating, The exception trace is similar to below-

java.lang.instrument.IllegalClassFormatException: Error while instrumenting class..
Caused by: java.io.IOException: Error while instrumenting class.
Caused by: java.lang.IllegalStateException: Class <class-name> is already instrumented.

I went through below link for a solution but could not get a way out:-

https://github.com/jacoco/jacoco/issues/32

The link says "The error indicates that there are two JaCoCo agents configured for the same process, Looks like activation of surefire-report-plugin leads to a doubled agent, which is not an exceptional case, but an error in configuration of JVM for tests" In my case it is not even doubled agent I guess as my argLine has set to only one jacoco agent.

In my case, the argLine is set to below-

javaagent:C:\\Users\\user\\.m2\\repository\\org\\jacoco\\org.jacoco.agent\\0.7.6.201602180812\\org.jacoco.agent-0.7.6.201602180812-runtime.jar=destfile=C:Users\\user\\git\\package\\target\\jacoco.exec

My pom.xml entry for jacoco-sonar configuration is as below -

<properties>
        <sonar.sources>src/main/java</sonar.sources>
        <sonar.tests>src/test/java</sonar.tests>
        <sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
        <sonar.jacoco.reportPaths>${project.basedir}/target/jacoco.exec</sonar.jacoco.reportPaths>
        <sonar.language>java</sonar.language>
        <sonar.binaries>${project.basedir}/target/classes</sonar.binaries>
        <sonar.inclusions>
            **/com/abc/service/impl/ABCServiceImpl.java,
            **/com/abc/dao/impl/ABCDAOImpl.java
        </sonar.inclusions>
    </properties>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.20</version>
                <configuration>
                    <skipTests>false</skipTests>
                    <argLine>-Xmx1024m -XX:MaxPermSize=256m ${argLine}</argLine>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
                <version>0.7.6.201602180812</version>
                <executions>
                 <execution>
                        <id>default-prepare-agent</id>
                        <goals>
                            <goal>prepare-agent</goal>
                        </goals>
                </execution> 
                <execution>
                    <id>default-instrument</id>
                    <goals>
                        <goal>instrument</goal>
                    </goals>
                </execution>
                <execution>
                    <id>default-restore-instrumented-classes</id>
                    <goals>
                        <goal>restore-instrumented-classes</goal>
                    </goals>
                </execution>
                    <execution>
                        <id>default-report</id>
                        <phase>prepare-package</phase>
                        <goals>
                            <goal>report</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

Note: If I remove the execution element for 'default-instrument' and 'default-restore-instrumented-classes' than the exception trace does not come but I get coverage = 0.0% on sonar dashboard, using these two execution elements give me correct code coverage but with lengthy stack trace on the console. Any help is appreciated.

4 Answers

I've also faced the same issue, but with Gradle. For me, the problem was with the following instructions

debug {
    testCoverageEnabled true
}

which I've added in accordance with one tutorial. It also instruments classes (as Jacoco does) and thus the exceptions are thrown.

Removing this instruction solved the problem for me.

If you are using pom.xml and jacoco plugin for build then you need to update the configuration at "prepare-agent" stage of build so that pre-instrumented classes are excluded as follows.

   <build>
            <plugins>
              <plugin>
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
                <executions>
                  <execution>
                <id>default-instrument</id>
                <goals>
                    <goal>instrument</goal>
                </goals>
                  </execution>
                  <execution>
                <id>default-restore-instrumented-classes</id>
                <goals>
                    <goal>restore-instrumented-classes</goal>
                </goals>
                  </execution>
                  <execution>
                <id>prepare-agent</id>
                <goals>
                  <goal>prepare-agent</goal>
                </goals>
                <configuration> 
                <excludes> 
                <exclude>*</exclude> 
                </excludes> 
                </configuration>      
                  </execution>
                  <execution>
                <id>report</id>   
                <goals>
                  <goal>report</goal>
                </goals>
                  </execution>
                </executions>
              </plugin>
            </plugins>
              </build>
Related