Jacoco unresolved dependency for the root project in multimodule build

Hello

I’m having a problem with making jacoco plugin behave correctly in multi-project setup.

So the setup

top-level
    |---subproject1
    |
   |---src
    |
   |---subproject1.gradle
    |---subproject2
    |
   |---src
    |
   |---subproject2.gradle
    |---build.gradle
    |---settings.gradle

Both subprojects are java projects with jacoco plugin applied. The root buid.gradle also has the jacoco plugin applied (so that jacocoAnt configuration is added to the top-level project). My goal is to merge all test execution data and to generate a report using this data. (I think it’s a pretty common task to do for a multimodule project). So I’m trying to merge the data in the root project using the following task

//build.gradle
apply plugin: 'jacoco'
  //...
//repositories configuration, etc
//...
  task(mergeCoverageInfoWithRootClasspath, type: JacocoMerge) {
    destinationFile = file("${buildDir}/jacoco/withrootclasspath/global.exec")
    jacocoClasspath = configurations.jacocoAnt +
            project(":subproject1").sourceSets.test.runtimeClasspath +
            project(":subproject2").sourceSets.test.runtimeClasspath
      executionData tasks.getByPath("subproject1:test")
    executionData tasks.getByPath("subproject2:test")
}

However if I try to run this task I get the following error

Could not resolve all dependencies for configuration ':jacocoAnt'.
> Could not find org.jacoco:org.jacoco.ant:0.6.2.201302030002.
  Required by:
      :top-level:1.0

Now, thats strange, because jacocoAnt is a known configuration and I manually checked that the artifact is present in .gradle/caches/modules-2.

The interesting part is I tried to use the jacocoAnt configuration from one of the subproject and it worked. No dependency resolution problems in this case.

//build.gradle
  //This code actually works and produces the merged execution information file
 task(mergeCoverageInfoWithSubprojectClasspath, type: JacocoMerge) {
    destinationFile = file("${buildDir}/jacoco/withsubprojectclasspath/global.exec")
    jacocoClasspath = project(":subproject1").configurations.jacocoAnt +
            project(":subproject1").sourceSets.test.runtimeClasspath +
            project(":subproject2").sourceSets.test.runtimeClasspath
      executionData tasks.getByPath("subproject1:test")
    executionData tasks.getByPath("subproject2:test")
}

Going forward with the report (JacocoReport task) I’ve got exactly the same problem – using root project configuration yields unresolved dependecy problem. Using subproject configuration works fine.

To conclude: 1. Is this the expected behavior? 2. Why the dependencies are not resolved for the root project, while they are resolved for the subprojects

Upon request I can provide the example project to reproduce this behavior.

My first guess is that the root project doesn’t have any repositories declared. Also, why do you put the runtime class paths on ‘jacocoClasspath’? If I’m not mistaken, ‘jacocoClasspath’ should only contain the JaCoCo libraries.

Thanks, Peter. Indeed I used the subprojects clause to configure repos instead of allprojects. And you’re right about the jacocoClasspath as well. In fact I don’t even need the merge task since JacocoReport task already takes a list of execution data to produce reports.