Creating fat jar using configuration does not work

Bascially I just want to create a fat jar in Project A by including a utils jar produced by Project B (not produced by it’s defualt default configuration and the issue might be around this). However I can’t get it to work. Here the snippet of the script:

Project A:

  configurations{

createAppJar }

dependencies {

createAppJar project(path: ‘:B’, configuration: ‘utilsArchives’) }

task appJar(type: Jar) {

dependsOn configurations.createAppJar

baseName ‘app’

from configurations.createAppJar.collect {

it.isDirectory() ? it : zipTree(it)

} }

Project B:

  configurations {

utilsArchives

}

task utilsJar(type: Jar) { … }

artifacts {

utilsArchives utilsJar }

The problem is that the content of ‘utils.jar’ is never expanded and included in the ‘app.jar’ when executing ‘appJar’ task.

I found out the issue is related to two things, either

createAppJar project(path: ':B', configuration: 'utilsArchives')

or

from configurations.createAppJar.collect

.

What I observed is that if I use the default configuration instead,

createAppJar project(':B')

(without ‘utilsArchives’), then it will expand and include the content of the default jar created by project B. But this is not what I need (I need the utils).

if I change the ‘appJar’ task to something like

from configurations.createAppJar

(without ‘collect’), then it’ll include ‘utils.jar’ in ‘app.jar’ but without expanding it and this is certainly not what I want either.

So am I doing something wrong here? Or this might be a Gradle bug?

Thanks!

I kinda found the solution:

http://forums.gradle.org/gradle/topics/right_way_to_copy_contents_from_dependency_archives

Basically,

configurations.createAppJar.collect

has to be called inside a clousre which is passed to ‘from’ instead of passing the resulting collection to ‘from’ directly. This essentially ‘defers’ the evaluation of the regarding dependency configuration to execution time.

What I don’t understand is why do we have to do this in this case?