Keshaw Kumar Keshaw Kumar - 1 month ago 16
Java Question

“IllegalStateException: Incompatible execution data for class in…” exception from Jacoco when run for an existing ear

I’m trying to test a legacy big fat EAR (app.ear) application using Arquillian and TestNG. To run the test I have added the testable war file (test.war) in to the existing app.ear and deployed on WildFly 10 server remotely.

@Deployment
public static EnterpriseArchive createDeployment(){
return ShrinkWrap.createFromZipFile(EnterpriseArchive.class, new File("../earapp/target/earapp-0.0.1-SNAPSHOT.ear"))
.addAsModule(Testable.archiveToTest(ShrinkWrap.create(WebArchive.class, "test.war")
.addClass(CurrencyConverterTest.class)
.addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml")));
}


The next part of my requirement is to get code coverage report after the tests are run. For that I’m using Jacoco and running it with Jacoco Maven Plugin.

<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.7.201606060606</version>
<executions>
<execution>
<id>default-prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>default-report</id>
<goals>
<goal>report</goal>
</goals>
</execution>
</plugin>


The app.ear gets deployed and the even the tests are running fine but when it comes to generate the report the Jacoco is failing with and exception “IllegalStateException: Incompatible execution data for class in Jacoco ………”

The exception is coming only for the class which contains the test cases. If I exclude that class (CurrencyConverterTest.class) using exclusion tag in Jacoco Maven Plugin the exception goes away but the reports generated by Jacoco contains no data. Also I’ve checked jacoco.exec and as far as I can say it contains valid data.

Since I cannot share the proprietary code I’m working with, I’ve created three simple projects on github to emulate the same.


  • Project 1 (currencycoverter): This project has one stateless ejb with a remote interface having three methods.

  • Project 2 (earapp): This project creates the ear file using project 1 as ejb module.

  • Project 3 (eartest): This project test the ear generated by project 2.



To me it looks like that there is some bug in the Jacoco code but I might be wrong also. Please help me out.

Update: Steps to build the projects shared on git repo

Step 1: Check out all the three projects and import into eclipse as eclipse projects.

Step 2: Run maven command clean instll for project 1 (currencyconverter)

Step 3: Run maven command clean package for project 2 (earapp). This will create an ear file in the target directory.

Step 4: Start a WildFly 10 in standalone mode on the local machine.

Step 5: Run maven command clean install for project 3 (eartest). This will use the ear generated in step 3 and deploy it in WildFly 10 application server and run the tests.

Answer

Unfortunately your example can't be built:

[ERROR] Failed to execute goal on project eartest:
Could not resolve dependencies for project com.sg.eartest:eartest:jar:0.0.1-SNAPSHOT:
Could not find artifact org.jboss.osgi.metadata:jbosgi-metadata:jar:3.0.1.Final in central (https://repo.maven.apache.org/maven2)

Also it will be simpler to play with it, if it would be located in single GitHub repository.

However:

Make sure that you use exact same version of JaCoCo in all modules under test.

And make sure that JVM under test is terminated gracefully, otherwise you mind receive corrupted "jacoco.exec" file, because by default it is saved during JVM shutdown. In earlier versions of JaCoCo such corrupted files might cause

IllegalStateException: Incompatible execution data for class in Jacoco

(as per https://github.com/jacoco/jacoco/issues/95#issuecomment-17271597)

The error message in case of truncated files has been improved in JaCoCo version 0.7.7 - https://github.com/jacoco/jacoco/pull/397 And it is a good practice to use latest released versions as they bring bug-fixes and improvements - http://www.eclemma.org/jacoco/trunk/doc/changes.html

Finally - seems that your tests located completely in a separate module from main code under test. "report" mojo creates report for classes of the current module. Use "report-aggregate" to aggregate coverage across modules - its documentation can be found at http://www.eclemma.org/jacoco/trunk/doc/report-aggregate-mojo.html Some examples were mentioned in https://groups.google.com/forum/#!msg/jacoco/8zjkSseaxD4/QOux-Ws-AgAJ