Gradle Knowledge Patch
Load this skill when writing, reviewing, debugging, or upgrading Gradle builds, plugins, Tooling API clients, or test infrastructure. Inspect the project's wrapper, build scripts, settings, plugin versions, JVM selection, and tests before applying guidance.
Reference index
| Reference | Topics |
|---|---|
| CLI, tooling, and platforms | Wrapper, console, daemon, reports, Tooling API, TestKit, platforms |
| Configuration Cache and modeling | Configuration Cache, Isolated Projects, lazy configuration, providers, collections |
| Dependencies, publishing, and distributions | Dependency resolution, verification, publications, signing, archives, distributions |
| JVM, languages, and build logic | JVM toolchains, Kotlin, Groovy, Scala, ANTLR, native builds, plugin authoring |
| Gradle 9 migration | Runtime floors, removed APIs and options, changed defaults, migration replacements |
| Testing, quality, and problems | Test discovery, reports, metadata, Problems API, validation, PMD |
First-pass compatibility audit
- Read
gradle/wrapper/gradle-wrapper.properties; do not infer the Gradle version from a locally installed executable. - Identify the daemon JVM separately from Java compilation and test toolchains. A build can target an older JVM than the one running Gradle.
- Inventory Kotlin, Groovy, Android, Develocity, Plugin Publishing, quality, and test-framework plugin versions before changing the wrapper.
- Search build logic for removed conventions, process helpers, Kotlin DSL shortcuts, custom archive behavior, and implicit test inputs.
- Run representative builds with Configuration Cache and review its report; warning mode does not preserve entries for incompatible tasks.
- Inspect publications, archive contents and metadata, dependency verification, test discovery, and included-project directories after an upgrade.
Breaking changes and required migrations
Run the daemon on a supported JVM
- Gradle 9 daemons require Java 17 or newer. Launchers and clients may start on Java 8 only if they can locate a Java 17+ daemon.
- Keep compilation, tests, and workers on their intended Java toolchains; do not raise target compatibility merely to satisfy the daemon.
- Apply
jvm-toolchainswhen usingValidatePluginswithout another JVM plugin, and enable native access when starting Tooling API clients on Java 25.
Update Kotlin and Groovy build logic
- Gradle 9 embeds Kotlin 2.2 and Groovy 4. Recompile plugins and fix changed Kotlin nullability bounds, Groovy package or module changes, and dynamic delegate lookup assumptions.
- Replace Kotlin script-instance labels with
project,settings, orgradle. Remove"name"()domain-object shortcuts, eager provider access, catalog library or bundle access inplugins {}, andkotlinDslPluginOptions.jvmTarget. - Do not rely on Groovy child projects finding missing properties or methods in a parent. Qualify access and use the rejection preview during migration.
- Add explicit dependencies for
groovy-test,groovy-console, andgroovy-sql;localGroovyno longer supplies them.
Replace removed Gradle APIs
- Remove
-c/--settings-file,-b/--build-file, andGradleBuild.buildFile; use standard settings and build layouts. - Replace convention APIs with extensions. Configure
warandeartasks directly and use thebaseextension for base-plugin properties. - Replace
Project.execandProject.javaexecand their script helpers with injected execution services or task types. - Replace integer Unix modes with
FilePermissions,IBM_SEMERUwithIBM, legacy IDEA test directories withtestSourcesandtestResources, andWriteProperties.outputFilewithdestinationFile. - Replace
GroovySourceSetandScalaSourceSetwith their source-directory-set counterparts. ExposeActionmethods instead of removedorg.gradle.utilclosure helpers.
Make test tasks explicit
- Custom
Testtasks no longer inherit classes or runtime classpaths from the built-intesttask. Configure both or create a JVM test suite. - A test task fails when sources exist but no tests are discovered and no
filters apply. Set
failOnNoDiscoveredTests = falseonly for an intentionally empty result. - For non-class JUnit Platform engines, configure
testDefinitionDirs; do not create dummy suite classes merely to trigger discovery.
Recheck archives and publications
- Archive tasks are reproducible by default: sorted entries, fixed timestamps, and normalized directory and file permissions. Opt back into filesystem metadata only for consumers that require it.
- A visible outgoing configuration does not join
assembleorarchivesautomatically. Wire its artifact into both lifecycles explicitly. - Do not mutate Gradle Module Metadata after an eagerly created publication has been populated from the same component. Signing follows the key's OpenPGP signature version.
Enforce stricter project and plugin contracts
- Every included project directory must exist, be writable, and be a directory.
- Make Gradle-derived classes abstract when they expose
@Injectgetters. - Treat
ConfigurationVariant.descriptionasProperty<String>and handleRootComponentIdentifierplus future component-identifier implementations. - Give every
@Optionalplugin property an input or output annotation; use@Internalalone for ignored properties.
Configuration Cache and isolation
Understand fallback and failure behavior
- Configuration Cache is preferred but optional. Known unsupported features can trigger a documented non-cache fallback; a task-execution cache problem aborts immediately.
- Incompatible tasks discard the entry even with
org.gradle.configuration-cache.problems=warn. - Task-completion listeners must be providers from registered build services. Use the unsupported-listener escape hatch only as temporary migration aid.
Diagnose cache behavior deliberately
- Enable
org.gradle.configuration-cache.integrity-check=trueonly while troubleshooting because it increases entry size and slows cache I/O. - Read-only mode can consume an existing entry without writing one, which suits untrusted or ephemeral CI jobs.
- Environment-backed project properties invalidate an entry only when read during configuration. Providers consumed solely during execution can observe a changed value while the entry is reused.
Keep configuration lazy
- Prefer
registerand role-based configuration factories tocreate. - Pass providers to configuration inheritance and publishing variant APIs.
- Use
AttributeContainer.addAllLaterwhen source attributes must remain lazy; imported values track the source, but later destination values win. - Use
DomainObjectCollection.elementsto carry collection values and task dependencies without forcing realization; usedisallowChanges()to freeze membership without freezing contained objects.
Treat Isolated Projects as a migration mode
- Enable with
--isolated-projectsororg.gradle.isolated-projects=true. Theorg.gradle.unsafenames are deprecated aliases. - Remove mutable cross-project and build access. Use diagnostics to find violations; dangerous-ignore mode is experimental migration scaffolding, not a production setting.
High-value current capabilities
Provision and select JVMs
- Daemon JVM criteria can auto-provision a matching JDK when a resolver is
installed;
updateDaemonJvmrecords per-platform URLs and criteria. - Toolchains can require GraalVM Native Image, and
JAVA_HOMEparticipates in Java toolchain auto-detection. - Daemon toolchains are stable. Java 25 and Java 26 can run the daemon and serve as toolchains, subject to third-party tool compatibility.
Improve unattended command-line builds
- Use
--non-interactiveororg.gradle.console.interactive=falseto disable prompts. UseNO_COLORto suppress color without disabling rich-console progress and animation. - Use
--console=coloredfor color without rich rendering,--task-graphto visualize dependencies without execution, andtasks --provenanceto find task registration sites. - Configure Wrapper retries and bearer authentication carefully, restrict credentials by host, and prefer signed distributions for authenticity.
Build richer test and problem integrations
- Test-event reporters can emit nested Gradle binary and HTML results with timestamped metadata for externally run tests.
- JUnit Platform data and attachments flow into HTML and XML, and metadata listeners expose the structured events to build logic.
- Problems can carry typed structured additional data that Tooling API clients retrieve through matching view interfaces.
- Stream large TestKit output through
BuildResult.getOutputReader()and close the reader after processing.
Use lazy publishing and distributions
distribution-baseprovides distribution support without creatingmain.- Create ad hoc components from the publishing extension and pass
Provider<ConsumableConfiguration>to variant methods to avoid realization until publication. - Configure Maven POM distribution management directly on
MavenPublication.
Verification checklist
- Run
./gradlew help, the relevant build and verification tasks, and at least one representative Configuration Cache reuse cycle. - Confirm the daemon JVM and each Java toolchain with diagnostic output.
- Check that custom tests execute, framework initialization failures are visible, and HTML/XML report consumers accept the current schema and timing.
- Inspect
artifactTransforms, task provenance, publication metadata, archive entry order and timestamps, and dependency-verification diagnostics where relevant. - Re-run composite and included builds, especially those with custom project directories or configuration-time task execution.