What does the dependsOn declaration do for a Gradle task, and what is its effect on the build?
answer
- must run before + must be included
- builds the execution DAG
- name / Task / TaskProvider / closure
- lifecycle tasks = empty + dependsOn edges
- topological sort
basics
~10 sdependsOn declares that another task must run before this one. Gradle adds the named task to the build's task graph and executes it first whenever this task is requested.
solid answer
~40 s`dependsOn` declares an explicit ordering relationship: when task A `dependsOn` task B, requesting A guarantees B runs first (and B is included in the graph even if not asked for directly). You can pass task names as strings (`dependsOn("compileJava")`), a `Task`/`TaskProvider` reference, or a collection/closure that resolves to tasks. Gradle uses these edges to build the execution DAG, then topologically sorts it so every dependency precedes its dependent. Crucially, `dependsOn` means "must run before" AND "must be included" — it is the core mechanism for chaining work. Lifecycle tasks like `build` are nothing more than empty tasks aggregating many `dependsOn` edges (e.g. `build` depends on `assemble` and `check`).
code
kotlin · 6 linestasks.register("release") {
group = "distribution"
dependsOn("build") // by name
dependsOn(tasks.named("javadoc")) // lazy TaskProvider
}
// running :release runs build (and everything build depends on) firstgo deeper
State the two effects: the dependency runs first and is included in the build. Give a simple by-name example.
Mention the DAG / topological sort and the various accepted argument types (name, Task, TaskProvider, collection).
Connect dependsOn to lifecycle aggregate tasks (build/check/assemble) and contrast it with output-wiring; note laziness of TaskProvider.
Frame dependsOn as the coarse-grained edge in the build's dependency model and discuss when to prefer it vs richer wiring across a multi-module build.
## What `dependsOn` is `dependsOn` is the primary way to declare an **explicit dependency** between Gradle tasks. Saying task `A.dependsOn(B)` asserts two things: 1. **Inclusion** — if `A` is in the task graph, `B` is pulled in too, even if nobody requested `B` directly. 2. **Ordering** — `B` must complete before `A` starts. ## How it shapes the execution DAG Gradle separates the build into two phases. During **configuration**, all `dependsOn` edges are recorded. Before execution, Gradle assembles a **directed acyclic graph (DAG)** of every requested task plus everything reachable through dependency edges, then performs a **topological sort** so each task runs only after all its dependencies. With parallel execution (`--parallel` / worker API), independent branches can run concurrently, but a `dependsOn` edge is always honored. ## Ways to declare it ```kotlin tasks.register("deploy") { dependsOn("build") // by name (String) dependsOn(tasks.named("test")) // by TaskProvider — lazy, preferred dependsOn(myJarTask) // by Task/TaskProvider reference dependsOn("a", "b", "c") // multiple at once } ``` You can also pass a `Provider`, a `Callable`/closure, or a `Collection` that resolves to tasks. Passing a `TaskProvider` (from `tasks.named(...)` / `tasks.register(...)`) is preferred because it stays **lazy** and doesn't force the dependency task to be configured eagerly. ## Lifecycle / aggregate tasks Many built-in tasks carry **no action of their own** — they exist purely to group other tasks via `dependsOn`. The Java plugin's `build` task `dependsOn` `assemble` and `check`; `check` `dependsOn` `test`; `assemble` `dependsOn` `jar`. Running `./gradlew build` therefore pulls in the whole chain. You create your own aggregate tasks the same way: register an empty task and add `dependsOn` edges to the real work. ## What `dependsOn` does NOT do It does not pass data between tasks, and it does not wire task *outputs* to *inputs* (that is inferred-dependency territory). It is a coarse "run this first" edge.
- If you request only task A and A dependsOn B, does B run?Yes. dependsOn pulls B into the graph and runs it before A, even though you never asked for B directly.
- Does dependsOn pass any data or files from B to A?No. It only enforces ordering and inclusion. Sharing data requires wiring B's outputs to A's inputs (inferred dependencies), not dependsOn.
Like a recipe step that says 'preheat the oven before baking' — the bake step won't start until the preheat finishes, and asking to bake automatically schedules the preheat.
saying these in an interview costs you the question
- Saying dependsOn transfers outputs/data between tasks — it only orders and includes.
- Claiming the dependency task runs only if explicitly requested — it is pulled in automatically.