3

I have a large Maven multiproject build with PowerMock-based unit tests. I'm generating a "target/jacoco.exec" in the child modules, with plugin configuration in the overall parent pom for the child modules. I have an additional child module that just uses "report-aggregate", and which specifies the various child modules as dependencies. This all basically works.

I'm now trying to integrate this data with SonarQube. It appears that the version of the SonarQube Java Analyzer that is installed doesn't know how to handle multiple jacoco.exec files, it will only process a single one. So, I'm trying to get the "merge" goal to work. I read the docs on this goal, but I'm obviously not doing something correctly, as it's just not finding the data files.

In the same child module that I'm using "report-aggregate", I did the following:

         <plugin>
            <groupId>org.jacoco</groupId>
            <artifactId>jacoco-maven-plugin</artifactId>
            <version>0.7.8</version>
            <executions>
                <execution>
                    <id>report-aggregate</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>report-aggregate</goal>
                    </goals>
                </execution>
                <execution>
                   <id>merge</id>
                   <goals>
                       <goal>merge</goal>
                   </goals>
                   <configuration>
                       <fileSets>
                           <fileSet>
                               <directory>../childmodule1/target</directory>
                               <include>*.exec</include>
                           </fileSet>
                           <fileSet>
                               <directory>../childmodule2/target</directory>
                               <include>*.exec</include>
                           </fileSet>
                           ... several more
                       </fileSets>
                   </configuration>
                </execution>
            </executions>
        </plugin>

When I ran "mvn clean install" from the top-level, it eventually processed the "jacoco-aggregate" child module, and produced the following output:

[INFO] ------------------------------------------------------------------------
[INFO] Building jacoco-aggregate 2.3.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ jacoco-aggregate ---
[INFO] Deleting ...\jacoco-aggregate\target
[INFO] 
[INFO] --- jacoco-maven-plugin:0.7.8:merge (merge) @ jacoco-aggregate ---
[INFO] Skipping JaCoCo merge execution due to missing execution data files
[INFO] 
[INFO] --- maven-resources-plugin:2.6:resources (filter) @ jacoco-aggregate ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory ...\jacoco-aggregate\src\main\resources
[INFO] 
[INFO] --- depends-maven-plugin:1.2:generate-depends-file (generate-depends-file) @ jacoco-aggregate ---
[INFO] Created: ...\jacoco-aggregate\target\classes\META-INF\maven\dependencies.properties
[INFO] 
[INFO] --- jacoco-maven-plugin:0.7.8:instrument (default-instrument) @ jacoco-aggregate ---
[INFO] 
[INFO] --- jacoco-maven-plugin:0.7.8:restore-instrumented-classes (default-restore-instrumented-classes) @ jacoco-aggregate ---
[INFO] 
[INFO] --- jacoco-maven-plugin:0.7.8:report (default-report) @ jacoco-aggregate ---
[INFO] Skipping JaCoCo execution due to missing execution data file.
[INFO] 
[INFO] --- maven-javadoc-plugin:2.10.4:jar (module-javadoc-jar) @ jacoco-aggregate ---
[INFO] Not executing Javadoc as the project is not a Java classpath-capable package
[INFO] 
[INFO] --- jacoco-maven-plugin:0.7.8:report-aggregate (report-aggregate) @ jacoco-aggregate ---
[INFO] Loading execution data file ...\childmodule1\target\jacoco.exec
[INFO] Loading execution data file ...\childmodule2\target\jacoco.exec
... several more
[INFO] Analyzed bundle 'childmodule1' with 1 classes
[INFO] Analyzed bundle 'childmodule2' with 1 classes

As you can see, it executed the "merge" goal, but it didn't find any data files, even though the later "report-aggregate" goal did.

So I assume that the way I'm specifying the filesets, or something associated with it, is somehow wrong. What might be wrong here?

David M. Karr
  • 14,317
  • 20
  • 94
  • 199
  • Do you have all the modules listed in your parent pom ? under – Shek Feb 01 '17 at 19:54
  • try adding prepare-agent before report goal. – Shek Feb 01 '17 at 19:59
  • I have no modules listed in the parent pom, as it is just a parent pom, not an aggregator pom. I do have a separate aggregator pom, which only lists the overall modules to be built. I have a separate child module, called "jacoco-aggregate" that doesn't list modules, but lists the GAVs for the child modules that produce the jacoco.exec files that need to be integrated. – David M. Karr Feb 01 '17 at 20:34
  • Using prepare-agent at all would not be useful, as I'm using offline instrumentation, as powermock-based tests can't work with online instrumentation. In addition, I said above that there is nothing wrong with the "report-aggregate" goal, it's only the "merge" goal that is doing nothing. – David M. Karr Feb 01 '17 at 20:36
  • what if you remove the `fileSet` entries at all and let the default values play? worth to give it a try imho – A_Di-Matteo Feb 02 '17 at 08:42
  • Ah, I think I may have resolved this. The doc page states that the default lifecycle phase for this goal is "generate-resources". That seems odd to me. What is the point of merging these files at the point when they likely couldn't possibly exist yet? I simply added a setting of phase to "verify", and it appeared to find all of the specified jacoco.exec files, and the resulting coverage imported into SonarQube seems to reflect coverage in multiple modules. – David M. Karr Feb 02 '17 at 18:28
  • The other detail I was missing was that the "directory" references are wrong here. I assumed they were relative to the child module doing this work, but they appear to be relative to the "base" of the project. – David M. Karr Feb 06 '17 at 15:57

3 Answers3

3

Try moving the <fileSets> (as well as the <destFile/>, if any) into the <plugin><configuration> rather than the <execution><configuration>:

<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.7.8</version>
    <configuration>
        <fileSets>
            <fileSet>
                <directory>..</directory>
                <include>**/target/*.exec</include>
            </fileSet>
        </fileSets>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>merge</goal>
            </goals>
        </execution>
    </executions>
</plugin>
krevelen
  • 361
  • 3
  • 11
2

I had two issues with how I was specifying the "merge" goal:

  • The default phase for "merge" is "generate-resources". I can't imagine how that could ever be useful, as I don't see how these data files could ever be created before that phase. I changed it to "verify" and that worked better.

  • In the fileset, I was specifying directory paths relative to this child module, when I should have been specifying them relative to the root of the project. I removed the "../" from those paths, and that fixed this problem.

David M. Karr
  • 14,317
  • 20
  • 94
  • 199
0

My configuration is slightly different as I have a reporting child module, which should handles all other modules, neither child nor siblings, but cousins. I ended-up with a configuration lile:

                <fileSets>
                    <fileSet>
                        <directory>${project.build.directory}/../../../</directory>
                        <includes>
                            <include>**/*.exec</include>
                        </includes>
                    </fileSet>
                </fileSets>

Executing the following can help investigating configuration issues:

mvn org.jacoco:jacoco-maven-plugin:merge -X

But, as suggested in another answer, it requires moving the configuration from an execution block to the main plugin configuration.

blacelle
  • 2,199
  • 1
  • 19
  • 28