Walk through configuring kapt for a Java annotation processor in a Gradle Kotlin DSL build, including how processor arguments are passed.
answer
- plugins { kotlin("kapt") }
- Processor on kapt(...), runtime on implementation(...)
- kapt { arguments { arg(k, v) } } -> -Akey=value
- kaptTest / kaptAndroidTest per source set
- Wrong config = nothing generated
basics
~10 sApply the kotlin-kapt plugin, then add the processor with the kapt(...) line instead of implementation(...). If the processor needs options, pass them in a kapt { arguments { arg(...) } } block.
solid answer
~40 sTwo pieces: (1) apply the plugin with `kotlin("kapt")` in the `plugins {}` block; (2) declare each processor through the **`kapt("group:artifact:version")`** dependency configuration — the runtime library still goes on `implementation`. Processor options are passed in the `kapt { }` extension via `arguments { arg("key", "value") }`, which forwards them as standard `-Akey=value` processor arguments. For source sets there are per-set configurations like `kaptTest(...)` and `kaptAndroidTest(...)`. Useful global knobs (in `gradle.properties`): `kapt.include.compile.classpath=false` to stop scanning the compile classpath for processors, and `kapt.incremental.apt` / `kapt.use.worker.api` for performance. A common gotcha: putting the processor on `implementation` instead of `kapt` means it never runs and no code is generated.
code
kotlin · 16 linesplugins {
kotlin("jvm") version "2.1.0"
kotlin("kapt") version "2.1.0"
}
dependencies {
implementation("androidx.room:room-runtime:2.6.1")
kapt("androidx.room:room-compiler:2.6.1")
kaptTest("androidx.room:room-compiler:2.6.1")
}
kapt {
arguments {
arg("room.schemaLocation", "$projectDir/schemas")
}
}go deeper
Can apply the plugin and add a processor via kapt(...) by copying a snippet.
Distinguishes processor vs runtime dependencies, knows the kapt arguments block and per-source-set configs.
Explains how arg(...) maps to -Akey=value options and which gradle.properties knobs affect behavior/perf.
Standardizes kapt config across a multi-module build and can spot mis-scoped processor dependencies in review.
## Step 1 — apply the plugin ```kotlin plugins { kotlin("jvm") version "2.1.0" kotlin("kapt") version "2.1.0" // id: org.jetbrains.kotlin.kapt } ``` `kotlin("kapt")` applies the `kotlin-kapt` Gradle plugin, which adds the `kapt` dependency configurations and wires the stub-generation + processing tasks into compilation. ## Step 2 — declare the processor on the kapt configuration The **processor** (the `*-compiler`/`*-processor` artifact) goes on `kapt(...)`; the **runtime library** (annotations + helpers you call) goes on `implementation(...)`: ```kotlin dependencies { implementation("androidx.room:room-runtime:2.6.1") // runtime API kapt("androidx.room:room-compiler:2.6.1") // the processor } ``` Per source set there are matching configurations: **`kaptTest(...)`**, **`kaptAndroidTest(...)`** for test-only processors. ## Step 3 — pass processor arguments Processors are configured with `-Akey=value` options. kapt exposes this through the `kapt { }` extension: ```kotlin kapt { arguments { arg("room.schemaLocation", "$projectDir/schemas") arg("room.incremental", "true") } correctErrorTypes = true // when cross-processor generated types are involved } ``` Each `arg(...)` becomes a standard annotation-processor option passed to the processor's `processingEnv.options`. ## Step 4 — global tuning (gradle.properties) ```properties kapt.include.compile.classpath=false # don't scan compile classpath for processors kapt.incremental.apt=true # incremental APT (default true) kapt.use.worker.api=true # run via Gradle Worker API (default true) ``` ## Common mistakes - **Wrong configuration**: declaring the processor under `implementation` or `compileOnly` — it won't run, so no code generates and you get 'unresolved reference' to generated classes. - **Forgetting the plugin**: the `kapt(...)` configuration doesn't exist until `kotlin("kapt")` is applied. - **Putting runtime libs on kapt**: only the processor belongs there. ## Keywords `kotlin("kapt")`, `kapt(...)`, `kaptTest(...)`, `kapt { arguments { arg(...) } }`, `-Akey=value`, `gradle.properties` flags.
- What happens if you put the processor on implementation instead of kapt?The processor never runs, so no sources are generated; you'll see unresolved references to the classes the processor was supposed to create.
- How do processor arguments declared via arg(...) reach the processor?kapt forwards them as standard javac annotation-processor options (-Akey=value), readable through processingEnv.options inside the processor.
saying these in an interview costs you the question
- Putting the processor under implementation/compileOnly
- Thinking kapt arguments are JVM/system properties rather than -A processor options
- Forgetting to apply the kotlin("kapt") plugin before using kapt(...)
- Not knowing kaptTest exists for test-only processors