Trouble with Worker parameter injection

plugins

(Ben Chatelain) #1

This is my first attempt at using the new Worker API in a very simple project with the hope that I can make use of this is some of the plugins that I’ve created. I started with a working task that executes an external command and have refactored that task to submit work to a WorkerExecutor. Now I’m getting the following error when Gradle is trying to inject values into my Dumper (Runnable) class.

./gradlew dumpHeaders                                                                                                                                                                                                                                                                                              

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':dumpHeadersACDEClient'.
> A failure occurred while executing Build_gradle$Dumper
   > Could not create an instance of type Build_gradle$Dumper.
      > No service of type File available in DefaultServiceRegistry.

build scan

I understand from gradle/gradle#2574 that gradle is falling back to service injection, probably because the parameter types aren’t lining up.

Relevant code (full source):

class Dumper @Inject constructor(
    val sourceFolder: File,
    val outputFolder: File
): Runnable {...}

open class DumpHeadersTask @Inject constructor(
    val worker: WorkerExecutor
): DefaultTask() {
...
    @TaskAction
    fun dumpHeaders() {
        worker.submit(Dumper::class.java) {
            fun execute(config: WorkerConfiguration) {
                config.isolationMode = IsolationMode.NONE
                config.params(
                        File(sourceFolder, "$frameworkName.framework"),
                        File(outputFolder, frameworkName)
                )
            }
        }
    }

I was initially passing two String instances to config.params() when the constructor parameters are File, but now the types are the same. I’ve tried changing the types of both the parameters and arguments to String with no change besides the message of “No service of type String available in DefaultServiceRegistry”.

Any ideas on what might be the issue?

Note that both the task and worker classes are defined in my build.gradle.kts. I’m using Gradle 4.6 on macOS 10.13.3.


(Ben Chatelain) #2

I figured it out. The WorkerConfiguration was not getting configured with any parameters. The problem was the extra fun execute that was just a loose function inside the lambda. Removing that and the config. prefix resolved the issue.

Below is the example java code:

workerExecutor.submit(GenerateMD5.class, new Action<WorkerConfiguration>() { 
    @Override
    public void execute(WorkerConfiguration config) { ... }
}

Which is equivalent to the following Kotlin:

worker.submit(GenerateMD5::class.java) {
    // `this` is a WorkerConfiguration inside the block
}

Working code is now:

@TaskAction
fun dumpHeaders() {
    worker.submit(Dumper::class.java) {
        isolationMode = IsolationMode.NONE
        params(
            File(sourceFolder, "$frameworkName.framework"),
            File(outputFolder, frameworkName)
        )
    }
}