Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 631
Deepak S Avatar asked Aug 08 '17 06:08

Deepak S


2 Answers

As per my insight into this research: It is possible to also use offline-instrumented classes with the JaCoCo Java agent. In this case, the configuration is taken from the agent options. The agent must be configured in a way that pre-instrumented classes are excluded, e.g. with " excludes=* ". Otherwise it will result in error messages on the console if the agent instruments such classes again likewise in your case.

The agent jacocoagent.jar is part of the JaCoCo distribution and includes all required dependencies. A Java agent can be activated with the following JVM option:

-javaagent:[yourpath/]jacocoagent.jar=[option1]=[value1],[option2]=[value2]

For JaCoCo agent options, consider the following link: http://www.jacoco.org/jacoco/trunk/doc/agent.html

like image 61
Stuti Verma Avatar answered Nov 04 '22 22:11

Stuti Verma


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.

like image 21
Kamo Spertsian Avatar answered Nov 04 '22 22:11

Kamo Spertsian