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 pageshowhide
explore
- Plugin<Project> Implementation5 questions
- Plugin<Settings> & Build-Init Plugins6 questions
- Plugin ID Metadata & java-gradle-plugin5 questions
- Precompiled Script Convention Plugins5 questions
- Publishing to the Gradle Plugin Portal6 questions
- Testing Plugins with TestKit6 questions
- Plugin Validation & validatePlugins6 questions
- Unit Testing with ProjectBuilder5 questions
questions
page 2 of 2How would you design a layered set of convention plugins for a large multi-module build, and what pitfalls would you avoid?
basics
~10 sCreate 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.
What are the fundamental limitations of ProjectBuilder, and how do they shape a plugin's overall test strategy?
basics
~20 sProjectBuilder 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.
How do you build a multi-project hierarchy and force project evaluation with ProjectBuilder, and what are the pitfalls?
basics
~10 sBuild 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()).
What kinds of work should you avoid doing eagerly in Plugin<Project>.apply, and what should you do instead?
basics
~20 sDon'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.
How are services like ObjectFactory and ProjectLayout made available to a Plugin<Project>, and why use them instead of Project methods directly?
basics
~10 sGradle 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.
How do you apply a Settings convention plugin, and what makes its bootstrapping tricky?
basics
~20 sApply 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.
How and why would a Settings plugin call includeBuild, and what does composite-build inclusion accomplish?
basics
~20 sincludeBuild(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.
How do you run TestKit functional tests across multiple Gradle versions, and why does it matter?
basics
~10 sCall 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.
How do you keep TestKit functional tests isolated and reliable — temp project dirs, environment, and debugging?
basics
~20 sGive 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.
What kinds of problems does plugin validation report, and what is a TypeValidationProblem?
basics
~10 sA 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.
Can a single build publish multiple plugins to the Portal, and how do you structure the `gradlePlugin` block to do so?
basics
~10 sYes. 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.
What lifecycle hooks and APIs does the Settings object expose that a Settings plugin can use beyond repository/project setup?
basics
~10 sBeyond 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.
How can you validate plugins you did not author from their built artifacts, and why would you?
basics
~20 sUse 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.
How would you make plugin validation a reliable quality gate across an organisation's internal plugins?
basics
~10 sApply 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.
showing 31–44 of 44