Composite build lifecycle question

We have a huge number of builds and composite build was a great solution to create virtual projects to save developers’ time. Though I faced few annoying things. I decided not to include other modules into existing builds, but rather develop umbrella projects, which include all needed modules and can be submitted into separate Git repository.
Layout:
Project A (umbrella) includes two modules, depends on them and has a dependency substitution
Project B simple library project
Project C multi module project which depends on B
in one of the B’s submodules I am building fat jar, which filters runtime configuration and includes certain number of jar from it, i.e:

def validJars = ['a-*', 'b-*', 'c-*']
task fatJar(type: Jar) {
    dependsOn configurations.runtime
    zip64 = true
    from (configurations.runtime.collect{ zipTree(it) }) {
        include validJars
    }
    from sourceSets.main.output
    from (fileTree("$projectDir/data"){ includes = dataFiles }.files)
    destinationDir file("$projectStage")
    archiveName "fatjar.jar"
}

This list “validJars” includes project B. Thus when Gradle configures project C, it resolves runtime configuration and actually runs project B (binary dependency is substituted with project). It also builds it during execution phase, which is very annoying. I am trying to debug sources to understand to avoid building substituted dependency during configuration phase, but piece of advice would be appreciated.

OK, found solution myself. Not very elegant one, but working.
Move jar task into execution phase of an empty task, thus Gradle resolves configuration only while executing it.

task fatJar {
    doLast {
        jar {}
    }
}