Gradle expert
Skill kinhluan/rules-quarkus-skills/.agent-skills/gradle-expert
π€ Complete AI expert ecosystem for Modern Java, Quarkus & Bazel development βοΈβ‘οΈ Coverage for Vert.x, GraalVM, Maven/Gradle migration, and more π
npx -y skills add kinhluan/rules-quarkus-skills --skill gradle-expertAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 3 stars3 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Expert knowledge for Gradle Build Tool, dependency management, and Gradle-to-Bazel migration. Use for build configuration and project lifecycle questions.
SKILL.md
12.0 KB, as published. Nobody here has run it
gradle-expert
Keyword: gradle | Platforms: gemini,claude,codex
Modern Gradle Build Tool Expert Skill - Specialized in performance, dependency management, and polyglot builds.
Core Mandates
- DSL Proficiency: Expert in both Groovy DSL (
build.gradle) and Kotlin DSL (build.gradle.kts). - Dependency Configurations: Distinguish between
api,implementation,runtimeOnly, andtestImplementation. - Build Performance: Leverage Build Cache, Daemon, and Parallel execution to optimize feedback loops.
- Convention over Configuration: Prefer built-in plugins (
java-library,application,maven-publish) over custom logic.
build.gradle.kts Examples
Quarkus Project
// build.gradle.kts
plugins {
java
id("io.quarkus") version "3.20.1"
}
repositories {
mavenCentral()
}
val quarkusPlatformVersion: String by project // from gradle.properties
dependencies {
// BOM - manages all Quarkus versions
implementation(enforcedPlatform("io.quarkus.platform:quarkus-bom:${quarkusPlatformVersion}"))
// No versions needed - managed by BOM
implementation("io.quarkus:quarkus-rest")
implementation("io.quarkus:quarkus-arc")
implementation("io.quarkus:quarkus-hibernate-orm-panache")
// Test
testImplementation("io.quarkus:quarkus-junit5")
testImplementation("io.rest-assured:rest-assured")
}
java {
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
}
tasks.withType<Test> {
useJUnitPlatform()
systemProperty("java.util.logging.manager", "org.jboss.logmanager.LogManager")
}
Multi-Module with Version Catalog
# gradle/libs.versions.toml
[versions]
quarkus = "3.20.1"
jackson = "2.18.2"
junit = "5.11.4"
assertj = "3.27.3"
[libraries]
quarkus-bom = { module = "io.quarkus.platform:quarkus-bom", version.ref = "quarkus" }
quarkus-rest = { module = "io.quarkus:quarkus-rest" }
quarkus-arc = { module = "io.quarkus:quarkus-arc" }
quarkus-hibernate = { module = "io.quarkus:quarkus-hibernate-orm-panache" }
quarkus-junit5 = { module = "io.quarkus:quarkus-junit5" }
jackson-databind = { module = "com.fasterxml.jackson.core:jackson-databind", version.ref = "jackson" }
junit-bom = { module = "org.junit:junit-bom", version.ref = "junit" }
assertj = { module = "org.assertj:assertj-core", version.ref = "assertj" }
[plugins]
quarkus = { id = "io.quarkus", version.ref = "quarkus" }
// settings.gradle.kts
rootProject.name = "my-platform"
include("common", "service-user", "service-order")
// build.gradle.kts (root)
plugins {
java
alias(libs.plugins.quarkus) apply false
}
subprojects {
apply(plugin = "java")
repositories {
mavenCentral()
}
dependencies {
implementation(platform(libs.quarkus.bom))
implementation(platform(libs.junit.bom))
}
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(21))
}
}
}
// service-user/build.gradle.kts
plugins {
alias(libs.plugins.quarkus)
}
dependencies {
implementation(project(":common"))
implementation(libs.quarkus.rest)
implementation(libs.quarkus.arc)
implementation(libs.quarkus.hibernate)
testImplementation(libs.quarkus.junit5)
testImplementation(libs.assertj)
}
Dependency Configuration Decision Tree
Does the consuming module need this at compile time?
YES β Does the consuming module also see this in ITS public API?
YES β api (leaks to consumers' compile classpath)
NO β implementation (hidden from consumers)
NO β Is it needed at runtime only?
YES β runtimeOnly (e.g., JDBC drivers, SLF4J bindings)
NO β Is it only for tests?
YES β testImplementation
NO β compileOnly (e.g., annotation processors, provided-like)
Do vs Don't
// BAD - using 'api' everywhere leaks dependencies, slows compilation
dependencies {
api("com.google.guava:guava:33.4.0-jre") // Leaked!
api("io.quarkus:quarkus-hibernate-orm-panache") // Leaked!
}
// GOOD - only 'api' what consumers actually need in their code
dependencies {
api("com.example:shared-dto:1.0") // Consumers use these types
implementation("com.google.guava:guava:33.4.0-jre") // Internal only
implementation("io.quarkus:quarkus-hibernate-orm-panache")
}
Version Conflict Resolution Workflow
Step 1: Identify the conflict
# Show dependency tree for a specific configuration
./gradlew dependencies --configuration runtimeClasspath
# Filter for a specific module
./gradlew dependencyInsight --dependency jackson-databind --configuration runtimeClasspath
# Output:
# com.fasterxml.jackson.core:jackson-databind:2.18.2
# variant "compile" [
# Requested: 2.14.0 β conflict
# Selected: 2.18.2 β Gradle picked highest
# ]
Step 2: Understand Gradle's resolution strategy
Gradle uses highest version wins by default. This is usually safe but can break binary compatibility.
Step 3: Resolve
// Option A: Force a specific version (use sparingly)
configurations.all {
resolutionStrategy {
force("com.fasterxml.jackson.core:jackson-databind:2.18.2")
}
}
// Option B: Use a BOM/platform (preferred)
dependencies {
implementation(platform("com.fasterxml.jackson:jackson-bom:2.18.2"))
// All Jackson modules now use 2.18.2
}
// Option C: Exclude transitive dependency
dependencies {
implementation("some-lib:some-lib:1.0") {
exclude(group = "com.fasterxml.jackson.core", module = "jackson-databind")
}
}
// Option D: Fail on conflict (strict mode for CI)
configurations.all {
resolutionStrategy {
failOnVersionConflict()
}
}
Resolution Priority
| Priority | Strategy | When to use |
|---|---|---|
| 1st | BOM / platform() | When a BOM exists (jackson-bom, netty-bom, quarkus-bom) |
| 2nd | Version Catalog | Centralize versions in libs.versions.toml |
| 3rd | exclude() | When one lib brings a known bad transitive |
| 4th | force() | Last resort - overrides everything, can mask issues |
Common Errors & Fixes
"Could not resolve all dependencies"
// Cause: Missing repository or wrong coordinates
repositories {
mavenCentral()
// Add private repo if needed:
maven {
url = uri("https://nexus.example.com/repository/maven-releases/")
credentials {
username = providers.environmentVariable("MAVEN_USER").orNull
password = providers.environmentVariable("MAVEN_TOKEN").orNull
}
}
}
"Execution failed: A valid toolchain could not be found"
// Fix: Specify Java toolchain
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(21))
}
}
// Or in gradle.properties:
// org.gradle.java.home=/path/to/jdk21
Build cache not working
# gradle.properties
org.gradle.caching=true
org.gradle.parallel=true
org.gradle.daemon=true
org.gradle.jvmargs=-Xmx4g -XX:+HeapDumpOnOutOfMemoryError
// settings.gradle.kts - remote cache
buildCache {
local {
isEnabled = true
}
remote<HttpBuildCache> {
url = uri("https://cache.example.com/cache/")
isPush = System.getenv("CI") != null // Only push from CI
}
}
"Cannot change dependencies after configuration resolution"
// BAD - resolving a configuration during configuration phase
val runtimeJars = configurations.runtimeClasspath.get().files // Triggers resolution!
// GOOD - defer to execution phase
tasks.register("listDeps") {
val runtimeCp = configurations.runtimeClasspath
doLast {
runtimeCp.get().files.forEach { println(it) }
}
}
Slow builds diagnostic
# Generate build scan (interactive report)
./gradlew build --scan
# Profile locally
./gradlew build --profile
# Opens report in build/reports/profile/
# Check configuration cache compatibility
./gradlew build --configuration-cache
Slow builds optimization checklist
| Check | Action |
|---|---|
| Daemon enabled? | org.gradle.daemon=true in gradle.properties |
| Parallel builds? | org.gradle.parallel=true |
| Build cache? | org.gradle.caching=true |
| Configuration cache? | --configuration-cache (Gradle 8.1+) |
Unnecessary api deps? | Switch to implementation to reduce recompilation |
allprojects{} / subprojects{} blocks? | Migrate to convention plugins |
| Task Configuration Avoidance? | Use tasks.register not tasks.create |
Gradle-to-Bazel Migration
Configuration Mapping Table
| Gradle | Bazel | Notes |
|---|---|---|
api | exports = [...] | Visible to transitive consumers |
implementation | deps = [...] | Hidden from consumers |
runtimeOnly | runtime_deps = [...] | Not on compile classpath |
compileOnly | deps = [...] + neverlink = True | Compile but not package |
testImplementation | test target deps | Separate test target |
project(":sub") | "//sub:target" | Bazel label |
./gradlew build | bazel build //... | Build all |
./gradlew test | bazel test //... | Test all |
| Version Catalog | rules_jvm_external | Different mechanism |
Exporting Dependencies for Bazel
# Generate dependency list from Gradle
./gradlew dependencies --configuration runtimeClasspath \
| grep '\\---' | sed 's/.*--- //' | sort -u
# Then translate to rules_jvm_external format in MODULE.bazel
Advanced Patterns
- Build Scan: Using Gradle Build Scans for debugging performance and dependency issues.
- Custom Tasks: Writing idiomatic tasks using the Task Configuration Avoidance API.
- Version Catalogs: Managing versions and libraries centrally via
libs.versions.toml.
Expert Tips
- Avoid using the deprecated
compileconfiguration; useimplementationorapi. - Use
./gradlew dependencies --configuration runtimeClasspathto visualize the dependency graph. - Prefer Kotlin DSL for better IDE support and type safety in complex builds.
- Use
gradle wrapper --gradle-version=8.12to pin Gradle version for reproducibility. - Always use
tasks.register(lazy) overtasks.create(eager) for Task Configuration Avoidance. - Use
./gradlew build --dry-runto preview task execution order without running anything.
π Gradle Knowledge Sources
Directive: Use
web_fetchto find Kotlin DSL syntax, version catalog patterns, or Gradle-to-Bazel migration strategies if a build configuration is complex.
- Gradle Kotlin DSL Primer: Kotlin DSL Guide - Type-safe build scripts.
- Dependency Management: Managing Dependencies - Configurations, platforms, and catalogs.
- Gradle-to-Bazel Migration: Migrating from Gradle to Bazel - Step-by-step transition.
- Build Performance: Optimizing Gradle Builds - Cache, daemon, and parallel execution.
- Quarkus Gradle Tooling: Quarkus Gradle Guide - Plugin configuration.
References
- Gradle Official User Guide
- rules_jvm_external Documentation
- Gradle Version Catalogs
- Quarkus Documentation
Skill Interoperability
The gradle-expert π skill provides expertise in modern build DSLs and performance, supporting:
- rules-quarkus π§: Facilitates the migration of Gradle-based projects to Bazel.