skip to content

Plugin Validation & validatePlugins

The validatePlugins task and the type-validation problems it reports for missing or conflicting input and output annotations, plus failing on warnings. Interviewers ask because it catches task-authoring mistakes before your users do.

on this pageshow

questions

6

Why does Gradle require input/output annotations on task properties, and what breaks if validation is ignored?

level: juniorimportance: must knowfreq 48%

answer

  1. annotations drive up-to-date checking
  2. @Input/@InputFile/@OutputFile
  3. missing annotation -> task skipped wrongly
  4. stale outputs
  5. broken build cache

basics

~20 s

Annotations like @Input and @OutputFile tell Gradle which properties are inputs and outputs so it can do up-to-date checking and caching. Without them, Gradle may skip a task whose inputs actually changed, producing stale outputs.

solid answer

~40 s

Gradle decides whether to re-run a task by comparing its declared inputs and outputs against the last run. It only knows what those are from **annotations on the task's property getters** — `@Input`, `@InputFile`, `@OutputFile`, `@OutputDirectory`, `@Nested`, `@Internal`, etc. If a property is missing its annotation, Gradle can't track it, so the task may be wrongly judged up-to-date and skipped even though that input changed — a stale-output correctness bug. Missing output annotations break the build cache because Gradle doesn't know what to store/restore. `validatePlugins` exists precisely to catch these missing or wrong annotations before they ship. Ignoring validation warnings means shipping a plugin whose tasks have unreliable incremental behaviour for every consumer. That is why authors enable `failOnWarning` — to make the metadata provably correct.

code

kotlin · 5 lines
kotlin
abstract class Copyfy : DefaultTask() {
    @get:InputFile  abstract val source: RegularFileProperty
    @get:Input      abstract val header: Property<String>
    @get:OutputFile abstract val dest: RegularFileProperty
}

go deeper

for a junior

Explain that @Input/@Output annotations let Gradle decide whether to re-run a task, and missing ones cause stale outputs.

for a middle

Tie it to up-to-date checking and the build cache, and to why validatePlugins flags missing annotations.

for a senior

Discuss normalization (@PathSensitive), @Nested, and enforcing correctness via failOnWarning.

for a principal

Frame correct task metadata as a prerequisite for trustworthy caching/remote-cache strategy across the org.

## How Gradle avoids redundant work Gradle is an *incremental* build tool. Before executing a task it asks: "have any inputs changed, and are the outputs still present and unchanged?" If not, it marks the task **UP-TO-DATE** and skips it. This is what makes large builds fast. ## Where the input/output knowledge comes from Gradle learns a task's inputs and outputs from **annotations on the getters** of the task type: - `@Input` — a simple value input (String, Int, etc.). - `@InputFile` / `@InputDirectory` / `@InputFiles` — file content inputs. - `@OutputFile` / `@OutputDirectory` — produced files. - `@Nested` — a nested object whose own annotated properties count. - `@Internal` — explicitly *not* tracked. - `@PathSensitive` — how file paths are normalized for comparison. ## What breaks without correct annotations 1. **Stale outputs (correctness).** A file input missing `@InputFile` isn't tracked; change the file and Gradle still skips the task, leaving wrong outputs. 2. **Broken build cache.** Without proper output annotations Gradle can't store/restore results, so caching either fails or restores incorrect data. 3. **Lost parallelism / work avoidance.** Gradle can't reason about overlapping outputs safely. ## Why validation is the safeguard `validatePlugins` statically checks that every relevant getter is annotated and the annotations are consistent. A missing annotation is a `TypeValidationProblem`. By default it's only a warning, so it's easy to ship a broken plugin — which is exactly why authors set `failOnWarning = true`. ```kotlin abstract class Copyfy : DefaultTask() { @get:InputFile abstract val source: RegularFileProperty // tracked content @get:Input abstract val header: Property<String> // tracked value @get:OutputFile abstract val dest: RegularFileProperty // produced file } ``` ## Takeaway Annotations are not bureaucracy — they are the contract that makes incremental builds and caching *correct*. Validation enforces that contract.

  • What concretely happens if a file input lacks @InputFile?
    Gradle won't track that file's content. If the file changes, the task is still considered up-to-date and is skipped, so the outputs are stale and wrong.
  • How do annotations relate to the build cache?
    The cache key is built from declared inputs, and outputs are stored/restored based on @Output* annotations. Missing or wrong annotations make caching either ineffective or incorrect.

The annotations are like a recipe's ingredient list: if you forget to list an ingredient, the cook (Gradle) thinks nothing changed and serves yesterday's dish even though you swapped the flour.

saying these in an interview costs you the question

  • Saying annotations are optional 'documentation' — they are functional and drive incremental builds.
  • Believing Gradle auto-detects inputs/outputs without annotations.

context

open as a page

How do you make plugin validation problems fail the build instead of just warning?

level: middleimportance: must knowfreq 50%

basics

~10 s

Configure the ValidatePlugins task with failOnWarning = true. Then any TypeValidationProblem becomes a build failure rather than a warning, so missing annotations break the build.

open as a page

What does the validatePlugins task do, and when does it run in a plugin build?

level: middleimportance: must knowfreq 55%

basics

~10 s

validatePlugins is a task added by the java-gradle-plugin. It inspects your custom task and plugin types and reports problems such as task properties missing input/output annotations.

open as a page

What kinds of problems does plugin validation report, and what is a TypeValidationProblem?

level: seniorimportance: should knowfreq 38%

basics

~10 s

A TypeValidationProblem is a single issue validatePlugins found on a task or plugin type — most often a property with no input/output annotation, or conflicting annotations like both @Input and @OutputFile on one getter.

open as a page

How can you validate plugins you did not author from their built artifacts, and why would you?

level: seniorimportance: nice to knowfreq 20%

basics

~20 s

Use Gradle's external-plugin validation (a ValidatePlugins-style task pointed at the plugin classes/jars rather than your own sources). It runs the same TypeValidationProblem checks on third-party or downstream plugins so you can gate them in CI.

open as a page

How would you make plugin validation a reliable quality gate across an organisation's internal plugins?

level: principalimportance: nice to knowfreq 18%

basics

~10 s

Apply java-gradle-plugin everywhere, enable failOnWarning and enableStricterValidation through a shared convention plugin, run validatePlugins in CI on every plugin repo, and validate published artifacts for third-party plugins.

open as a page