skip to content

Core Plugin Families

The plugins that ship with Gradle: the JVM language plugins, the base and lifecycle-base tasks everything hooks into, and the reporting plugins. Interviewers ask so you can state precisely what applying `java` gives you.

on this pageshow

explore

questions

20

What lifecycle tasks does the Gradle 'base' plugin contribute, and what does each one mean?

level: juniorimportance: must knowfreq 70%

answer

  1. assemble = artifacts, no checks
  2. check = verification, no artifacts
  3. build = assemble + check
  4. clean = delete buildDirectory
  5. lifecycle tasks have no actions

basics

~10 s

The base plugin adds 'assemble' (build all artifacts), 'check' (run all verification like tests), 'build' (assemble + check together), and 'clean' (delete the build directory).

solid answer

~40 s

Applying the `base` plugin contributes four standard lifecycle tasks. **`assemble`** produces all the build's outputs/artifacts (e.g. archives) but runs no verification. **`check`** runs all verification tasks (tests, linters) without producing artifacts. **`build`** is the umbrella task that depends on both `assemble` and `check` — it's the default 'do everything' entry point. **`clean`** deletes the project's `layout.buildDirectory`. These are *lifecycle* tasks: they carry no actions themselves, they just aggregate work by depending on other tasks. Other plugins (like `java`) hook into them — e.g. `jar` becomes a dependency of `assemble`, and `test` becomes a dependency of `check`. This convention is why `gradle build` behaves consistently across very different project types.

code

kotlin · 10 lines
kotlin
plugins { base }

// A custom artifact task hooked into the lifecycle
val bundle by tasks.registering(Zip::class) {
    from("src/dist")
    archiveFileName.set("app.zip")
}

tasks.named("assemble") { dependsOn(bundle) }
// now `gradle build` -> assemble (runs bundle) + check

go deeper

for a junior

Name the four tasks and say one sentence each. Knowing assemble=artifacts, check=verify, build=both, clean=delete is enough.

for a middle

Explain that they are action-less lifecycle tasks and that build = assemble + check, plus how java wires jar/test into them.

for a senior

Discuss the lifecycle-base vs base split, the archives configuration, and how custom plugins should hook into the lifecycle rather than redefine it.

for a principal

Frame the lifecycle as a cross-project contract that makes gradle build uniform across heterogeneous modules, and a governance lever for org-wide build conventions.

## What the base plugin is The `base` plugin is one of Gradle's most foundational core plugins. It does not know anything about Java, Kotlin, or any language. Its entire job is to establish the **standard build lifecycle** — a small set of well-known, empty 'umbrella' tasks that every other plugin can attach work to. Because of this convention, `gradle build` means the same thing whether you're building a Java library, a C++ binary, or a documentation site. Internally `base` is split: it applies `lifecycle-base` (which contributes the lifecycle tasks and the `clean` task) and then layers on the archive/artifact conventions (the `archives` configuration, base archive naming via the `base { }` extension). ## The four lifecycle tasks These are **lifecycle tasks**: tasks with no `@TaskAction` of their own. They exist purely to depend on real work tasks, so running them runs everything wired into them. - **`assemble`** — aggregates all tasks that *produce* the project's artifacts. It performs no verification. With the `java` plugin, `jar` is wired in as a dependency, so `assemble` builds the JAR. - **`check`** — aggregates all *verification* tasks. With `java`, the `test` task is wired in. Running `check` runs your tests but does not build distributables. - **`build`** — depends on **both** `assemble` and `check`. It is the canonical 'build the whole thing and verify it' entry point. (Note: `build` is *not* the same as the `build` *directory*.) - **`clean`** — a `Delete` task that removes `layout.buildDirectory` (by default `build/`). `lifecycle-base` also lets plugins register `clean<TaskName>` rules so individual outputs can be cleaned. ## How other plugins hook in The power is in the wiring. A plugin doesn't redefine the lifecycle — it *contributes* to it: ```kotlin tasks.named("assemble") { dependsOn(myArtifactTask) } tasks.named("check") { dependsOn(myVerificationTask) } ``` This is why a single `gradle build` invocation in a multi-language project does the right thing for every plugin applied. ## The `archives` configuration `base` also creates the `archives` configuration. Artifacts added to it (e.g. via `artifacts { archives jarTask }`) are picked up by `assemble`. This is the legacy hook that older plugins used to register their outputs. ## Why it matters Most build authors apply `base` *transitively* (the `java` plugin applies it for you). You apply it directly when writing a custom plugin or a build that produces artifacts but isn't a JVM project, and you want the standard lifecycle vocabulary for free.

  • Does `assemble` run your tests?
    No. `assemble` only produces artifacts. Tests are verification and are wired into `check`. Only `build` (which depends on both) runs both.
  • What's the difference between the `build` task and the `build/` directory?
    Unrelated. `build` is a lifecycle task (assemble + check); `build/` is the default output directory (`layout.buildDirectory`) that `clean` deletes.

Think of the lifecycle tasks as labeled empty boxes on a shelf. Plugins drop their real work into the right box; running build just empties every box in order.

saying these in an interview costs you the question

  • Saying `assemble` runs tests — it explicitly does not.
  • Confusing the `build` task with the `build/` directory.
  • Thinking lifecycle tasks have their own actions rather than just aggregating dependencies.

context

open as a page

What does applying the core `java` plugin give you in a Gradle build?

level: juniorimportance: must knowfreq 78%

basics

~10 s

The java plugin adds the main and test source sets, compile tasks (compileJava, compileTestJava), processResources, the jar task, and the standard build/check/assemble lifecycle wiring.

open as a page

What does the `project-report` plugin add to a Gradle build, and which report tasks does it contribute?

level: juniorimportance: must knowfreq 45%

basics

~10 s

Applying project-report adds tasks that generate diagnostic reports: dependencyReport, taskReport, propertyReport, and the aggregate projectReport task, plus an HTML dependency report.

open as a page

What is a SourceSet in Gradle's Java plugin, and what two source sets does the plugin create by default?

level: juniorimportance: must knowfreq 70%

basics

~10 s

A SourceSet is a named group of source files compiled together. The java plugin creates two by default: main (production code) and test (test code that depends on main's output).

open as a page

You wrote a custom task that packages a distribution. How do you make `gradle build` run it, and where should it hook?

level: middleimportance: must knowfreq 55%

basics

~10 s

Make assemble depend on your packaging task: tasks.named("assemble") { dependsOn(myTask) }. Since build depends on assemble, gradle build will then run it.

open as a page

In the `java-library` plugin, what is the difference between the `api` and `implementation` configurations?

level: middleimportance: must knowfreq 85%

basics

~10 s

api dependencies leak onto consumers' compile classpath (they're part of your public API); implementation dependencies are internal — visible at your own compile/runtime but hidden from consumers' compile classpath, only present at runtime.

open as a page

Explain how a source set's compile and runtime classpaths relate to its `*Implementation`, `*CompileOnly`, and `*RuntimeOnly` configurations.

level: middleimportance: must knowfreq 60%

basics

~10 s

For a source set, compileClasspath resolves from its *CompileClasspath configuration (fed by implementation + compileOnly), and runtimeClasspath from its *RuntimeClasspath configuration (fed by implementation + runtimeOnly).

open as a page

What does the `application` plugin add, and how do you configure it to run a Java program?

level: juniorimportance: should knowfreq 70%

basics

~10 s

The application plugin applies java, adds a run task that launches your main class, an application {} extension where you set mainClass, and distZip/distTar/installDist tasks that package the app with start scripts.

open as a page

What exactly does the `clean` task delete, and how do the `base { }` extension and `archives` configuration relate to it?

level: middleimportance: should knowfreq 40%

basics

~20 s

clean is a Delete task that removes the project's build directory (layout.buildDirectory, default build/). The base { } extension sets archive naming and output dirs; the archives configuration collects artifacts that assemble builds — both feed outputs under build/.

open as a page

What is the difference between the `base` plugin and the `lifecycle-base` plugin?

level: middleimportance: should knowfreq 45%

basics

~10 s

lifecycle-base is the smaller plugin that only adds the lifecycle tasks (assemble, check, build) and clean. base applies lifecycle-base and adds archive conventions like the archives configuration and the base { } naming extension.

open as a page

What does the `build-dashboard` plugin do, and how does the `buildDashboard` task discover which reports to include?

level: middleimportance: should knowfreq 40%

basics

~10 s

build-dashboard adds a buildDashboard task that generates a single HTML index linking to every report-producing task that runs in the same build invocation (tests, dependency reports, etc.).

open as a page

What is the `htmlDependencyReport` task and how does it behave in a multi-project build?

level: middleimportance: should knowfreq 38%

basics

~10 s

htmlDependencyReport (from project-report) generates a browsable HTML report of resolved dependencies. In a multi-project build it aggregates every subproject into one report with a project selector.

open as a page

How do you change or add source and resource directories for a source set, for example to support a non-standard project layout?

level: middleimportance: should knowfreq 50%

basics

~10 s

Configure the source set's java.srcDirs (or resources.srcDirs) inside the sourceSets block. Use srcDir(...) to add a directory or assign srcDirs = listOf(...) to replace the defaults.

open as a page

As a build platform owner, how do you leverage the base/lifecycle-base convention so heterogeneous modules (JVM, JS, docs) all respond uniformly to `gradle build` in CI?

level: seniorimportance: should knowfreq 30%

basics

~10 s

Ensure every module applies a plugin in the base family so it has assemble/check/build, then hook each module's real work into assemble (artifacts) or check (verification). CI then just runs gradle build everywhere.

open as a page

How would you decide between `java`, `java-library`, and `application` across a multi-module build, and what do they contribute respectively?

level: seniorimportance: should knowfreq 55%

basics

~20 s

Use java for a basic compilable module, java-library for a reusable library that other modules depend on (it adds api for public deps), and application for an executable entry-point module (adds run + a distribution). The latter two both apply java.

open as a page

How do reporting tasks decide where to write their output, and how would you relocate all reports for a project?

level: seniorimportance: should knowfreq 30%

basics

~10 s

Reporting plugins honor the ReportingExtension (reporting { baseDirectory }), which defaults to build/reports. Setting reporting.baseDirectory relocates the base under which report tasks (project-report, build-dashboard, tests, coverage) write.

open as a page

What does a source set's `output` represent, and how is it used to wire one source set against another?

level: seniorimportance: should knowfreq 35%

basics

~10 s

A source set's output is a FileCollection of its compiled classes (classesDirs) and processed resources (resourcesDir). You add it to another set's classpath to let that set see these compiled artifacts.

open as a page

Walk through registering a custom source set (e.g. for integration tests) and wiring up a Test task to run it.

level: seniorimportance: should knowfreq 55%

basics

~10 s

Create the source set with sourceSets { create("integrationTest") }, add main's output to its classpaths, register a Test task pointing at its testClassesDirs/classpath, and hook it into check.

open as a page

What does the core `groovy` plugin add on top of `java`, and what is joint compilation?

level: middleimportance: nice to knowfreq 38%

basics

~10 s

The groovy plugin applies java, adds a groovy source directory to each source set, registers compileGroovy/compileTestGroovy tasks, and supports joint compilation — compiling interdependent Groovy and Java sources together.

open as a page

When would you apply `project-report`/`build-dashboard` versus relying on the built-in `dependencies`/`tasks` tasks or external tooling?

level: seniorimportance: nice to knowfreq 22%

basics

~10 s

Use the built-in dependencies/tasks tasks for quick interactive console checks. Apply project-report/build-dashboard when you need persisted, browsable, aggregated HTML reports for CI archival or a single index across reports.

open as a page