2.4-rc-2 Possible regression project.tasks

Can no longer find all tasks via the task container after upgrading to 2.4-rc-2.

The crux of the problem is that Line 71 evaluates to an empty set

However, by calling .discoverTasks() and finding a known task by its name that task becomes available via the task container.

println "I can find a known task after .discoverTasks() :" + it.tasks.findByName('publishMavenJavaPublicationToJcenterRepository')

def jcenterTasks = it.tasks.findAll { it.name.contains('ToJcenterRepository') }
println "Found jcenterTasks by path: ${jcenterTasks}"

This may be related to: Gradle 2.4-rc-1 fails to retrieve GradleProject model but there are a number of things at play here:

  • Multi-module project
  • The code in question is in a plugin under buildSrc
  • The tasks being searched for (…ToJcenterRepository) are added by the maven-publish plugin.
  • afterEvaluate is used
  • The tasks being searched for are on subprojects accessed via evaluatedProject.subprojects.each

What version were you upgrading from? This particular change to the publishing tasks was made in Gradle 2.2.


upgrading from 2.3…

If your plugin worked in 2.3 it was probably only incidental. The tasks created by the ‘maven-publish’ plugin aren’t available from afterEvaluate { } post 2.2. For what you are doing, you should really be using live collections.

evaluatedProject.subprojects.each {
    snapshotTask.dependsOn it.tasks.matching { task -> task.name.contains('ToJcenterRepository') }

@mark_vieira here’s a simplified version:

I’m still convinced there is something wrong. The tasks cannot be accessed, at execution time, via subProject.tasks.findAll(...)

@luke_daley: So the publishing tasks here aren’t being created unless we explicitly reference them by name. I’ve confirmed this was not the behavior in 2.3. Is this by design?

Yes, this is generally the point of the rules based model. We know about the existence of things (and some of their characteristics) without having to actually create them unless they are really needed. Tasks are somewhat special in that we have to bridge them back to the non rules world.

As the new publishing stuff is incubating (yes, still) we won’t class this as a regression. I will however add a potential breaking change to the release notes, which we should have had.

What’s the actual use case here @Adrian_Kelly? What is this code trying to do?

@luke_daley the use case is:

  • multi-module project
  • ability to have a custom task ‘snapshotTask’ depend on all publication tasks (within subprojects) which publish to jcenter.

idea being a horizontal compile -> test -> publish in a multi module project.

Simplest backwards compatible solution is to do this:

task snapshotTask { task ->
  subprojects {
    afterEvaluate {
      task.dependsOn tasks.names.findAll { it.endsWith("ToJcenterRepository") }*.path

This would be simpler to express via rules, but we don’t yet have constructs for crossing boundaries via rules.

@luke_daley thanks! Nice alternative.