Gradle 2.5: Upload task not working?

So I’m trying to upgrade the Grails build to Gradle 2.5, however I’m encountering an issue with the custom upload task:

     task installToHomeDist(type: Upload) {
        configuration = configurations.archives
        repositories {
            flatDir name: 'libs', dirs: distInstallDir
        }
    }

See https://github.com/grails/grails-core/blob/master/build.gradle#L357 for context.

So we created this custom Upload task for each subproject and when gradle installToHomeDist was run it would place all the of the JAR files produced by each subproject into the GRAILS_HOME/dist directory.

Now in Gradle 2.5 it does nothing and no dist directory is created at all and no JAR files are copied. So how do we get back the previous behaviour?

AFAICT, this isn’t an intended behaviour change, so there’s no canned answer to “So how do we get back the previous behaviour?”.

Would you mind creating a cut down example that we can use to debug?

So this turned out to be nothing to do with the Upload task. Instead this syntax works in Gradle 2.3 but fails in Gradle 2.5:

task install(dependsOn:  subprojects.collect { Project p -> p.tasks.withType(PublishToMavenLocal)})

In Gradle 2.3 with the above defined in your root build it will execute all subproject PublishToMavenLocal tasks. In Gradle 2.5 it executes none of them.

It seems that as of Gradle 2.5 it is no longer possible to reference tasks of subprojects from the top-level project? Seems a major breaking change to me. Doing the following in the top level build.gradle prints an empty list:

def subtasks = subprojects.collect { Project p -> p.tasks.withType(PublishToMavenLocal) }.flatten()
println "subtasks = $subtasks"

@luke_daley
It seems another occurrence of Change of behaviour for @Finalize between 2.3 and 2.4 release

I tried doing:

subprojects.each {
    it.tasks.realize()    
}

But that resulted in

What went wrong:
    A problem occurred evaluating root project 'gradletest'.
    > A problem occurred configuring project ':one'.
       > Failed to apply plugin [id 'org.gradle.help-tasks']
          > Cannot create 'tasks.help' using creation rule 'tasks.addPlaceholderAction(help)' as model element 'tasks' is no longer mutable.

@Graeme_Rocher1 you may be able to get access to the publishing task using this approach: 2.4-rc-2 Possible regression project.tasks

No, it’s not that drastic. Do you really think we’d make such a change intentionally?

Tasks created via model rules aren’t always created like “legacy” tasks are. This is a performance optimization. Tasks are expensive to create, so we don’t want to create them if they aren’t going to be used. What’s going wrong here is that we aren’t interpreting constructs like tasks.withType() as an indication that the task is required. We can fix that.

I’ve raised [#GRADLE-3318] tasks.withType(SomeType) does not realise tasks defined via model rules. As it’s a regression, we’ll prioritise it for 2.6.

In the meantime, @Francois_Guillot’s work around should get this flowing again.

Sorry, forgot to give more insight on your last problem.
Looks like you’re realizing the tasks too early, and after, the org.gradle.help-tasks plug-in tries to use a rule but it’s not possible anymore, because the tasks container is finalized, and not mutable anymore.

Try calling ‘realize’ just before it is needed, and also maybe reorder your plug-ins application, so that the org.gradle.help-tasks plug-in is applied before your problematic task.

Bear in mind that this is a temporary solution, until this type of constructs, between rule and non-rule world is dealt properly.

@luke_daley This bug is still open and Gradle 2.7 is nearly out. The workarounds suggested by @Adrian_Kelly don’t appear to work for me.

The is the only thing that worked, which seems like a bit of hack:

task install(dependsOn: [populateDependencies, grailsCreateStartScripts]) { task ->
   subprojects { Project project ->
      if(!project.name.startsWith('grails-test-suite')) {
          task.dependsOn("$project.name:publishToMavenLocal")
      }
  }
}

@Graeme_Rocher1 a fix for depending on tasks by type ( .withType(...) ) is in master. It will ship with 2.8.

We just tried our build with this problem with 2.8. It still isn’t working, even though the bug, https://issues.gradle.org/browse/GRADLE-3318, says it was fixed in 2.8-rc1

Here’s a bit more info on what we’re seeing.

There is a subset of our projects that do define dependencies ‘fooinput( project(’:someProj’) )’

In our main build file we do:

configurations.fooinput.allDependencies.withType(ProjectDependency) { projectDep →

projectDep.dependencyProject.tasks.withType(PublishToMavenLocal) { publishToMavenLocalTask ->
    gentask.dependsOn(publishToMavenLocalTask)
}

}

This does not result in any of the gentask.dependsOn that we expect.

The workaround we’ve had to use is:

 configurations.fooinput.allDependencies.withType(ProjectDependency) { projectDep ->
     projectDep.dependencyProject.tasks.findAll { it.name.contains("publishToMavenLocal") }.each { task ->
         gentask.dependsOn(task)
    }
}

Thanks,
Jim

1 Like