0

I have a task in build.gradle, looking like this:

task sourceJar(type: Jar, dependsOn: classes) << {
  classifier = 'sources'
  from sourceSets.main.allSource
}

Running gradle sourceJar creates a jar file in libs/ but it is empty (does not include any sources, just the manifest). Removing << fixes it for some reason, the jar is created properly, but screws up other things (the subprojects now lose the compile dependencies, that are defined for them specifically).

So, three (maybe, four?) questions here: (1) what's wrong? Why sourceSets are empty when the task is defined with <<? (2) why does removing << fix it? My understanding is that it just makes the insides of the block to be executed "inline", every time, not just when the task is specifically exacuted. (3) How to fix this? I can't just remove <<, because, like I said, it screws up other things (but see question #4). (4) Why does removing << screws up subprojects? Is this expected? To clarify, here is what I am talking about:

subprojects {
 apply plugin: 'java'
 dependencies {
   compile project(':a')
 }

 task  cp  << {
  println ("PROJECT " + project.name + ">> " + sourceSets.main.runtimeClasspath.collect { it.absolutePath }.join(':'))
 }
}

project(':b') {
  dependencies {
   compile project(':c')
  }
}

Running gradle -q b:cp prints out

PROJECT b>> b/build/classes/main:b/build/resources/main:a/build/libs/a.jar:c/build/libs/c.jar

(I removed the absolute paths). This is what I want.

Now, if I remove << from the file, and run gradle -q b:cp again, I get this

PROJECT a>> a/build/classes/main:a/build/resources/main:/a/build/libs/a.jar
PROJECT b>> b/build/classes/main:b/build/resources/main:a/build/libs/a.jar
PROJECT c>> c/build/classes/main:c/build/resources/main:a/build/libs/a.jar

This is wrong in two ways: first, I did not ask it to be run for all three subprojects, just for b, and second, notice that b does not have c in its classpath any more.

Can someone with a clue please help me figure out what's going on here ... I am really about to give up and switch to sbt (yes, it is a threat!).

Dima
  • 39,570
  • 6
  • 44
  • 70

1 Answers1

1

When you declare a task of type:Jar, you do not have to use <<, because you're effectively extending a jar task which already has all the required << declared correctly. But first it sounds like you need to read up on what << means and about gradle's configuration and execution phases.

Please see Peter's answer here: Why is my Gradle task always running?

(<< is gradle shorthand for doLast any task code that isn't enclosed in doLast or isn't annotated by << is executed in the configuration phase and not execution phase. This can cause your printlns for example to be executed when the task isn't explicitly invoked, because all tasks are configured even if they are not executed)

Second, your cp task isn't extending a task type. so this needs << in its definition.

 task  cp  << { ... }
Community
  • 1
  • 1
RaGe
  • 22,696
  • 11
  • 72
  • 104
  • Ok, this helps, thanks! I do know what `<<` means, what threw me off is that with the (almost) the same syntax, sometimes you need it, and sometimes you need to not have it :) I am still not sure I understand why having `<<` in the jar task messes it up, BTW. You explained why I don't need it, but not why I can't have it. – Dima Mar 04 '16 at 12:59