# Init Script and Convention Plugins

**URL:** <https://discuss.gradle.org/t/init-script-and-convention-plugins/44105>\
**Category:** Help/Discuss\
**Created:** [October 26, 2022, 8:05pm UTC](https://discuss.gradle.org/t/init-script-and-convention-plugins/44105 "2022-10-26T20:05:11Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![jdamour98](https://avatars.discourse-cdn.com/v4/letter/j/ce7236/32.png) [@jdamour98](https://discuss.gradle.org/u/jdamour98)\
**Post date:** [October 26, 2022, 8:05pm UTC](https://discuss.gradle.org/t/init-script-and-convention-plugins/44105/1 "2022-10-26T20:05:11Z")

</div>

I am using a project with a Convention Plugin to apply common logic between submodules. The project structure looks like this:

```gradle
my-project/
├── buildSrc/
│ └── .../java-common.gradle # Here the 'java' plugin is applied
├── module-1/
│ └── build.gradle # Here the 'java-common' convention is applied
└── module-1/
    └── build.gradle # Here the 'java-common' convention is applied

```

This build succeeds fine locally. However, our CI system applies an init script aggregates SourceSets:

```gradle
rootProject {
    // Define variable for subprojects to actually consider as "source"
    ext {
        coverageSourceProjects = ["module-1"]
    }

    afterEvaluate {
        task jacocoAggregateReport(type: JacocoReport) {
            // Gather execution data from all subprojects
            executionData fileTree(project.rootDir.absolutePath).include("**/build/jacoco/*.exec")

            println("Coverage sources: " + coverageSourceProjects)
            allprojects.each { project ->
                if (project.name in coverageSourceProjects && project.hasProperty("sourceSets")) {
                    sourceSets project.sourceSets.main
                }
            }
            reports {
                xml.enabled true
                html.enabled true
                csv.enabled false
            }
        }
    }
}

```

Since the InitScript executes before the `buildSrc` directory is evaluated and the java plugin gets applied, non of the modules have any SourceSets defined. Therefore, this init script errors out:

```gradle
A problem occurred configuring root project 'my-project'.
> Could not get unknown property 'sourceSets' for project ':module-1' of type org.gradle.api.Project.

```

How can I evaluate the Init Script **after** the buildSrc plugin has compiled?

---

<div class="post-metadata">

**Author:** ![Vampire](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/vampire/32/9082_2.png) [@Vampire](https://discuss.gradle.org/u/Vampire)\
**Post date:** [October 27, 2022, 12:25am UTC](https://discuss.gradle.org/t/init-script-and-convention-plugins/44105/2 "2022-10-27T00:25:52Z")

</div>

There are quite some bad practices in that snippet and fixing some might help with your issue.  
For example, do not use `afterEvaluate`, instead use `pluginManager.withPlugin` to react to the plugin you want to use being applied.  
Also don’t use eager task creation, but use task configuration avoidance, then the configuration of the task is done as late as possible and only if the task is actually going to be executed unless something else is disturbing.

But what is probably one of the major problems is, that you happily cross project boundaries when you really shouldn’t, but instead use safe cross-project publishing.

Actually you should probably not try to build that aggregation manually anyway, but simply use the built-in `jacoco-aggregation` plugin which does it in the right way.
