1

I'm currently working on a Java OSGi project(based on Apache felix runtime) with a project setup like the one below:

  • pkg | parent maven project
  • persistence | real plugin
  • persistence.tests | test plugin (indeed a Fragment project with fragment host the persistence plugin above )
  • ... others like the ones above

Basically I use maven + tycho to manage the lifecycle of the project. the whole stuff flows through a continuos integration pipeline which involves jenkins for building, testing, deploying and forwarding code analysis to a Sonarqube server. Just like mentioned above, tests are implemented through Fragment projects pointing OSGi bundles to be tested. In these tests I make use of EasyMock library to generate mocked OSGi bundles. In order to make Sonarqube aware of tests coverage I had to add Jacoco (maven plugin) into my sets of tools. After a few adjustments to the configuration of my parent pom.xml file I ended up with something that is working partially: jacoco code coverage is only working for classes included in test plugins (the fragment projects). As you may guess - though better than nothing - this result is far from being useful. I need to evalute test coverage on real OSGi bundles. After some googling I understood that the problem could be linked to the usage of EasyMock library, since this alterate original classes during execution causing a mismatch between test classes and real classes. According to my understanding, to solve I need to disable jacoco on-the-fly instrumentation and use offline instrumentation instead.

Nevertheless I'm not able to understand :

  • what does this really means
  • how to do it

Can someone kindly revert on this ?

This is the maven command i'm running to generate jacoco report

mvn -f com.mycompany.osgi.myproject.pkg/pom.xml clean test

Below my current parent pom.xml

<?xml version="1.0" encoding="UTF-8"?><project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.osgi</groupId>
<artifactId>com.mycompany.osgi.myproject.pkg</artifactId>
<packaging>pom</packaging>
<version>1.0.0</version>

<properties>
    <tycho.version>1.0.0</tycho.version>
    <surefire.version>2.16</surefire.version>
    <main.basedir>${project.basedir}</main.basedir>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <jacoco.version>0.7.9</jacoco.version>

    <!-- Sonar-JaCoCo properties -->
<sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
<sonar.junit.reportPaths>${project.basedir}/target/surefire-reports</sonar.junit.reportPaths>
<sonar.jacoco.reportPaths>${project.basedir}/target/jacoco.exec</sonar.jacoco.reportPaths>
</properties>


<modules>

    <module>../com.mycompany.osgi.myproject.core.persistence</module>
    <module>../com.mycompany.osgi.myproject.core.persistence.tests</module> 

</modules>

<build>
        <plugins>
            <plugin>
          <groupId>org.jacoco</groupId>
          <artifactId>jacoco-maven-plugin</artifactId>
          <version>${jacoco.version}</version>
        </plugin>
    </plugins>
    <pluginManagement>
        <plugins>
            <plugin>
                <groupId>org.eclipse.tycho</groupId>
                <artifactId>tycho-compiler-plugin</artifactId>
                <version>${tycho.version}</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.eclipse.tycho</groupId>
                <artifactId>tycho-maven-plugin</artifactId>
                <version>${tycho.version}</version>
                <extensions>true</extensions>
            </plugin>


            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>${surefire.version}</version>


                <dependencies>
                    <dependency>
                        <groupId>org.apache.maven.surefire</groupId>
                        <artifactId>surefire-junit47</artifactId>
                        <version>${surefire.version}</version>
                    </dependency>
                </dependencies>

                <executions>
                    <execution>
                        <id>test</id>
                        <phase>test</phase>
                        <configuration>
                            <testClassesDirectory>${project.build.outputDirectory}</testClassesDirectory>
                        </configuration>
                        <goals>
                            <goal>test</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </pluginManagement>
</build>


<repositories>
    ...
</repositories>

<distributionManagement>
    ...
</distributionManagement>

Godin
  • 9,801
  • 2
  • 39
  • 76
Andrea Di Lisio
  • 465
  • 5
  • 17
  • 2
    The referenced thread is about PowerMock, not about EasyMock. AFAIK there is no problem in JaCoCo + EasyMock. Usually "tests and main code - different modules, SonarQube shows only coverage on tests" is because during analysis of classes of main module SonarQube should see exec file that is located in test module - https://stackoverflow.com/a/41740003/244993, so check this before, because offline instrumentation ( http://www.jacoco.org/jacoco/trunk/doc/offline.html ) not needed almost never except PowerMock, is not recommended, much harder to setup especially in case of OSGi, etc. – Godin Dec 14 '17 at 14:06
  • 1
    If the comment above doesn't help, then please provide [Minimal, **Complete**, and Verifiable example](https://stackoverflow.com/help/mcve) e.g. by sharing sample project similar to yours in GitHub, because just snippet of `pom.xml` is IMO clearly not enough to easily observe/reproduce your problem. – Godin Dec 14 '17 at 14:10
  • hi @Godin, I just removed my previous comment since apparently the problem was solved with your suggestions. basically what happens is that jacoco generated html reports are simply showing test classes but i'm able to instruct sonarqube to look where it should, with the help of parameter sonar.jacoco.reportPaths and sonar.junit.reportPaths. I'm editing my orginal post with this informations. Thank a lot for your precious support – Andrea Di Lisio Dec 15 '17 at 10:54
  • 1
    instead of editing question might be better to post answer on your own question ;) or maybe mark it as duplicate. BTW in case of `jacoco-maven-plugin` to cross boundaries of modules you can use `report-aggregate` - http://www.jacoco.org/jacoco/trunk/doc/report-aggregate-mojo.html – Godin Dec 15 '17 at 11:34

1 Answers1

1

As suggested by @Godin, my problems were solved using the following jacoco plugin configurations

<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>${jacoco.version}</version>
    <configuration>
        <dataFile>../com.mycompany.myproject.pkg/target/jacoco.exec</dataFile>
        <destFile>../com.mycompany.myproject.pkg/target/jacoco.exec</destFile>
        <outputDirectory>../com.mycompany.myproject.pkg/target/site/jacoco</outputDirectory>
    </configuration>
</plugin>

and this project configuration to instruct sonarqube to read expected resources

<properties>
        ...

        <!-- Sonar-JaCoCo properties -->
        <sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
<sonar.junit.reportPaths>com.mycompany.myproject.pkg/target/surefire-reports</sonar.junit.reportPaths>
        <sonar.jacoco.reportPaths>com.mycompany.myproject.pkg/target/jacoco.exec</sonar.jacoco.reportPaths>
    </properties>
Godin
  • 9,801
  • 2
  • 39
  • 76
Andrea Di Lisio
  • 465
  • 5
  • 17