skip to content

Authoring Plugins

Writing Gradle plugins: project and settings plugins, plugin id metadata, precompiled convention plugins, publishing, and TestKit functional tests. Interviewers ask because plugins are how build logic gets shared and versioned.

on this pageshow

questions

page 2 of 2

How would you design a layered set of convention plugins for a large multi-module build, and what pitfalls would you avoid?

level: seniorimportance: should knowfreq 40%

basics

~10 s

Create small, single-responsibility convention plugins (base, library, application, test, publishing) and compose them by applying lower-layer ones inside higher-layer ones. Avoid one monolithic plugin and avoid leaking module-specific logic into shared conventions.

open as a page

What are the fundamental limitations of ProjectBuilder, and how do they shape a plugin's overall test strategy?

level: seniorimportance: should knowfreq 28%

basics

~20 s

ProjectBuilder only covers the configuration phase in-process: no task execution, no real lifecycle/afterEvaluate, no real dependency resolution or configuration cache. So you pair broad ProjectBuilder wiring tests with focused TestKit tests for execution and lifecycle.

open as a page

How do you build a multi-project hierarchy and force project evaluation with ProjectBuilder, and what are the pitfalls?

level: seniorimportance: should knowfreq 30%

basics

~10 s

Build a root with ProjectBuilder.builder().build(), then children with .withParent(root).withName("child").build(). ProjectBuilder doesn't auto-evaluate, so afterEvaluate won't fire unless you trigger evaluation via internal APIs (ProjectInternal.evaluate()).

open as a page

What kinds of work should you avoid doing eagerly in Plugin<Project>.apply, and what should you do instead?

level: seniorimportance: should knowfreq 38%

basics

~20 s

Don't do expensive or side-effecting work in apply — no I/O, no resolving configurations, no eager tasks.create or forcing Property.get(). Register tasks lazily, wire Providers, and defer real work to task actions executed only when needed.

open as a page

How are services like ObjectFactory and ProjectLayout made available to a Plugin<Project>, and why use them instead of Project methods directly?

level: seniorimportance: should knowfreq 40%

basics

~10 s

Gradle injects services into a plugin via an @Inject constructor — e.g. ObjectFactory, ProjectLayout, ProviderFactory. You use them to create Property/Provider instances and resolve paths lazily, which is cleaner and configuration-cache friendly.

open as a page

How do you apply a Settings convention plugin, and what makes its bootstrapping tricky?

level: seniorimportance: should knowfreq 35%

basics

~20 s

Apply it via plugins {} in settings.gradle(.kts). The catch: the plugin must already be resolvable when settings is evaluated, so it comes from buildSrc, an included build under pluginManagement, or a published plugin in pluginManagement repositories.

open as a page

How and why would a Settings plugin call includeBuild, and what does composite-build inclusion accomplish?

level: seniorimportance: should knowfreq 38%

basics

~20 s

includeBuild(path) in a settings plugin wires another Gradle build into this one as a composite build. Gradle substitutes published dependencies with the included build's projects, letting you develop and consume a library or plugin together without publishing.

open as a page

How do you run TestKit functional tests across multiple Gradle versions, and why does it matter?

level: seniorimportance: should knowfreq 35%

basics

~10 s

Call withGradleVersion("8.5") on GradleRunner to run the build under a specific Gradle version. Parameterize the test over several versions to prove your plugin works across the range you support.

open as a page

How do you keep TestKit functional tests isolated and reliable — temp project dirs, environment, and debugging?

level: seniorimportance: should knowfreq 30%

basics

~20 s

Give each test a fresh temporary project directory (e.g. JUnit @TempDir), write its build/settings files there, and assert against it. TestKit runs in an isolated worker with its own Gradle user home, so tests don't depend on your machine.

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

Can a single build publish multiple plugins to the Portal, and how do you structure the `gradlePlugin` block to do so?

level: seniorimportance: nice to knowfreq 20%

basics

~10 s

Yes. Declare each plugin as a separate entry in the gradlePlugin { plugins { … } } block with its own id, implementationClass, displayName, description, and tags. One publishPlugins run uploads all of them.

open as a page

What lifecycle hooks and APIs does the Settings object expose that a Settings plugin can use beyond repository/project setup?

level: seniorimportance: nice to knowfreq 25%

basics

~10 s

Beyond include and resolution blocks, a Settings plugin can use settings.gradle hooks like settingsEvaluated, projectsLoaded, and projectsEvaluated, configure buildCache, set rootProject properties, enableFeaturePreview, and iterate rootProject to apply per-project conventions.

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

showing 31–44 of 44