How do you pass data into a WorkAction, and what are the constraints on those parameters?
answer
- interface extends WorkParameters
- managed Property/RegularFileProperty types
- isolated snapshot at submit
- processIsolation => serializable
- WorkParameters.None for no params
basics
~20 sDefine an interface extending WorkParameters with Gradle lazy-typed properties (Property, RegularFileProperty, etc.). Set them in the submit { } block. The action reads them via its parameters property. Values must be isolatable so Gradle can snapshot them.
solid answer
~40 sEach `WorkAction` is parameterized by a `WorkParameters` subtype — an interface with Gradle managed properties (`Property<T>`, `RegularFileProperty`, `ListProperty`, `MapProperty`, `ConfigurableFileCollection`, etc.). You declare it as the action's type argument; Gradle generates a `parameters` accessor. At submit time you populate it in the configuration block: `queue.submit(MyAction::class) { params -> params.x.set(...) }`. Crucially Gradle **isolates** (snapshots/serializes) the parameter values at submit time so the action sees a stable, decoupled copy — this is what makes process and classloader isolation safe and what allows the work to outlive the task action's stack frame. Therefore parameter values must be isolatable: prefer Gradle's `Provider`/`Property` types and serializable/`File`/primitive values; avoid passing live `Project`, `Task`, or arbitrary non-serializable objects. For a `noIsolation` queue with no parameters you can use `WorkParameters.None`.
code
kotlin · 18 linesinterface CompileParams : WorkParameters {
val sourceFile: RegularFileProperty
val release: Property<Int>
}
abstract class CompileAction : WorkAction<CompileParams> {
override fun execute() {
val src = parameters.sourceFile.asFile.get()
val rel = parameters.release.get()
// compile src targeting rel
}
}
// submit
queue.submit(CompileAction::class.java) {
it.sourceFile.set(file)
it.release.set(17)
}go deeper
Know you define a WorkParameters interface with Gradle property types and set them in the submit block.
Explain that values are snapshotted/isolated at submit and what that means for serializability and post-submit mutation.
Connect parameter isolation to process/classloader isolation correctness and configuration-cache compatibility.
Reason about parameter design as a stable cross-boundary contract; guide teams away from leaking build-model objects into workers.
## The parameters contract Every `WorkAction<P>` declares a parameter type `P : WorkParameters`. `WorkParameters` is a marker interface; you extend it with an interface of **Gradle managed properties**: ```kotlin interface CompileParams : WorkParameters { val sourceFile: RegularFileProperty val classpath: ConfigurableFileCollection val release: Property<Int> val defines: MapProperty<String, String> } ``` You never write the implementation — Gradle generates it (the properties are abstract/`val`-only). Inside the action you read them through the inherited `parameters` accessor: ```kotlin abstract class CompileAction : WorkAction<CompileParams> { override fun execute() { val src = parameters.sourceFile.asFile.get() val rel = parameters.release.get() } } ``` ## Isolation of parameter values When you call `submit`, Gradle takes an **isolated snapshot** of the parameter values. This means: - The action gets a stable copy even though `submit` returns immediately and the work runs later/elsewhere. - For `processIsolation`, the snapshot is **serialized** across the process boundary, so values must be serializable. - For `classLoaderIsolation`, values are reconstituted in the isolated classloader. Because of this snapshotting, **mutating the parameter objects after submit has no effect** on already-submitted work, and you must not pass references to live build model objects (`Project`, `Task`, `Configuration`). Pass resolved data: `File`s, strings, numbers, `FileCollection` contents, or other `Provider`s that resolve to isolatable values. ## No parameters If an action needs nothing, declare it as `WorkAction<WorkParameters.None>` and submit without a config block: ```kotlin queue.submit(PingAction::class.java) {} ``` ## Why interfaces, not data classes? Using managed-property interfaces lets Gradle wire laziness, provenance, and isolation uniformly — the same machinery as task inputs. It also means parameter wiring participates cleanly in the configuration cache, since everything is a `Provider`/`Property` Gradle already knows how to snapshot. ## Common pitfalls - Putting non-serializable fields in parameters and then using `processIsolation` → serialization failure at submit. - Capturing outer state in the `WorkAction` class (constructor injection of arbitrary services beyond what Gradle supports) instead of going through parameters. - Expecting later mutation of the params object to reach the worker — it won't; the snapshot is taken at submit.
- Why can't you pass a Project or Task into a WorkAction's parameters?They aren't isolatable/serializable and would couple worker code to the live build model, breaking process isolation and the configuration cache. Pass resolved data (files, strings, numbers) instead.
- What happens if you mutate the parameter object after calling submit?Nothing for the already-submitted unit — Gradle snapshots parameter values at submit time, so later mutations don't reach that worker.
saying these in an interview costs you the question
- Saying parameters are passed by live reference so changes after submit are visible.
- Putting non-serializable objects in parameters used with processIsolation.
- Implementing the WorkParameters interface yourself instead of letting Gradle generate it.