kapt compiler plugin
The kapt compiler plugin allows you to use existing Java annotation processors in Kotlin and works with both Maven and Gradle. It generates stub files from Kotlin source code and then runs the Java annotation processors on those stubs.
This enables Java-based annotation processing in your Kotlin projects for libraries like MapStruct and Data Binding.
Set up the plugin
You can configure the kapt plugin for Gradle, Maven, or use it from the command line.
Gradle
To use kapt in Gradle, follow these steps:
Apply the
kaptGradle plugin in your build script filebuild.gradle(.kts):plugins { kotlin("kapt") version "2.4.10" }plugins { id "org.jetbrains.kotlin.kapt" version "2.4.10" }Add the respective dependencies using the
kaptconfiguration in thedependencies {}block:dependencies { kapt("groupId:artifactId:version") }dependencies { kapt 'groupId:artifactId:version' }If you previously used the Android support for annotation processors, replace usages of the
annotationProcessorconfiguration withkapt. If your project contains Java classes, the kapt plugin processes them as well.If you use annotation processors for your
androidTestortestsources, the respectivekaptconfigurations are namedkaptAndroidTestandkaptTest. Note thatkaptAndroidTestandkaptTestextendkapt, so you can provide thekaptdependency, and it will be available both for production sources and tests.
Maven
You can set up kapt using either the <extensions> option to simplify setup or manually to get full control over kapt's execution.
Automatic configuration
You can simplify kapt configuration by enabling the <extensions> option for the Kotlin Maven plugin. In this case, you don't need to manually set up kapt's <execution> section with goals or source directories.
To automatically configure kapt, set the <extensions> option to true for the kotlin-maven-plugin in your pom.xml build file:
For more information on the <extensions> option, see Automatic configuration.
Manual configuration
To manually set up kapt in your Kotlin Maven project, add an execution of the kapt goal from kotlin-maven-plugin before the compile execution:
To configure the annotation processing mode, set the aptMode option in the <configuration> block. For example:
CLI
kapt is available as a standalone CLI tool in the binary distribution of the Kotlin compiler.
To run kapt from the command line, use:
For example:
See the full list of kapt-specific compiler options.
You can also pass all valid Kotlin compiler options. Run
kotlinc -helpto see them.
Configure annotation processors
kapt provides options to control how annotation processors are discovered, organized, and executed, including managing the processor classpath, inheriting processors from shared configurations, and keeping javac-specific processors active.
For more configuration options, such as passing options to annotation processors and javac, see Annotation processor configuration.
Configure processor classpath and discovery
You can disable the discovery of annotation processors that aren't included in kapt's processor path. This excludes unnecessary annotation processors from the compile classpath.
Gradle
Gradle uses compile avoidance to skip annotation processing during project rebuild, improving incremental build times with kapt. Particularly, annotation processing is skipped when:
The project's source files are unchanged.
The changes in dependencies are ABI-compatible. For example, when only function bodies change.
However, compile avoidance can't be used for annotation processors discovered on the compile classpath, since changes in their internal implementation require running the annotation processing tasks, even if the processors' ABI remains unchanged.
That's why we don't recommend using annotation processors from the compile classpath. To exclude these processors from kapt processing, add the kapt.include.compile.classpath property to your gradle.properties file:
With the option set to false, annotation processor dependencies that aren't included in the processor path (the kapt* configurations) are excluded from kapt processing.
Maven
To exclude annotation processors that aren't included in the kapt's processor path, set the includeCompileClasspath option to false in the <execution> section of the kapt plugin:
Alternatively, you can use the kapt.include.compile.classpath property in the <properties> section of your pom.xml:
With the option set to false, annotation processors that aren't included in the <annotationProcessorPaths> section are excluded from kapt processing.
If the includeCompileClasspath option isn't set and kapt detects an annotation processor on the compile classpath that isn't explicitly defined in the processor path, you'll see a deprecation warning:
Inherit annotation processors from superconfigurations
You can define a common set of annotation processors in a separate Gradle configuration as a superconfiguration and extend it further in kapt-specific configurations for your subprojects.
As an example, for a subproject using MapStruct, in your build.gradle(.kts) file, use the following configuration:
In this example, the commonAnnotationProcessors Gradle configuration is the common superconfiguration for annotation processing that you want to be used for all your projects. You use the extendsFrom() method to add commonAnnotationProcessors as a superconfiguration. kapt sees that the commonAnnotationProcessors Gradle configuration has a dependency on the MapStruct annotation processor. Therefore, kapt includes the MapStruct annotation processor in its configuration for annotation processing.
Keep Java compiler's annotation processors
By default, kapt runs all annotation processors and disables annotation processing by javac. However, you may need javac to run some annotation processors, such as Lombok.
In the Gradle build file, use the option keepJavacAnnotationProcessors:
If you use Maven, configure the plugin explicitly. See this example of setting up the Lombok compiler plugin.
Optimize kapt builds
kapt offers several Gradle-specific strategies to reduce annotation processing time, including running tasks in parallel, leveraging the build cache, caching processor classloaders, and using incremental annotation processing.
For more options that affect build behavior, such as error type correction, stub metadata stripping, and compile classpath scanning, see Behavioral options.
Run kapt tasks in parallel
kapt uses the Gradle Worker API to run annotation processing tasks. Using the Worker API lets Gradle run independent annotation processing tasks from a single project in parallel, which in some cases significantly decreases the execution time.
If you set the custom JDK version in the Kotlin Gradle plugin, kapt task workers use only the processIsolation() mode.
If you want to provide additional JVM arguments for a kapt worker process, use the input kaptProcessJvmArgs of the KaptWithoutKotlincTask:
Use Gradle build cache safely
Gradle caches kapt annotation processing tasks by default. However, annotation processors can run arbitrary code. This may result in unnecessary transformations of task inputs into outputs, or accessing and modifying files that Gradle doesn't track.
When annotation processors used in the build can't be properly cached, you can disable caching to prevent false-positive hits for kapt tasks. To do this, use the useBuildCache property in the build script:
Cache annotation processors' classloaders
Caching for annotation processors' classloaders helps kapt perform faster if you run many Gradle tasks consecutively.
To enable this feature, use the following properties in your gradle.properties file:
If you run into any problems with caching for annotation processors, disable caching for them:
Use incremental annotation processing
With Gradle, kapt supports incremental annotation processing by default so that only the changed files are re-processed.
Currently, incremental annotation processing works only if:
Incremental compilation is enabled.
All annotation processors in the build are incremental.
To disable incremental annotation processing, add this line to your gradle.properties file:
Analyze performance
kapt provides built-in diagnostics to help you understand annotation processing performance, including per-processor execution time reports and generated file counts to identify unused processors.
For more diagnostic options, such as file read history for debugging incremental processing and memory leak detection, see Diagnostics and statistics options.
Measure the performance of annotation processors
To get performance statistics on the annotation processors execution, use the showProcessorStats option. An example output:
You can dump this report to a file with the dumpProcessorStats option. For example, the following CLI command runs kapt and dumps the statistics to the ap-perf-report.file file:
Track the number of generated files
The kapt plugin can report statistics on the number of generated files for each annotation processor.
This helps track whether any unused annotation processors are included in the build. You can use the generated report to find modules that trigger unnecessary annotation processors and update the modules to avoid that.
To enable statistics reporting:
In your Gradle build file, set the
showProcessorStatsoption totrue:// build.gradle(.kts) kapt { showProcessorStats = true }In your
gradle.propertiesfile, set theverbosecompiler option totrue:# gradle.properties kapt.verbose=true
The statistics appear in the logs with the info level. You can see the Annotation processor stats: line followed by statistics on the execution time of each annotation processor. After these lines, there is the Generated files report: line followed by statistics on the number of generated files for each annotation processor. For example:
Generate Kotlin sources
kapt can generate Kotlin sources. To do that, write the generated Kotlin source files to the specified directory using processingEnv.options["kapt.kotlin.generated"]. Kotlin source files are then compiled together with the main sources.
Compiler options
Annotation processor configuration
Option | Description | How to set up |
|---|---|---|
| Controls the execution of kapt workflow stages:
| Gradle: not directly available; Gradle runs stubs and apt as separate tasks Maven:
<aptMode>stubsAndApt</aptMode>
CLI: |
| Classpath entries where annotation processors are discovered. | Gradle:
dependencies {
kapt("com.example:processor:1.0")
}
Maven:
<annotationProcessorPaths>
<annotationProcessorPath>...</annotationProcessorPath>
</annotationProcessorPaths>
CLI: |
| Comma-separated fully qualified class names of processors to run, bypassing discovery. | Gradle:
kapt {
annotationProcessor("com.example.MyProcessor")
}
Maven:
<annotationProcessors>
<annotationProcessor>com.example.MyProcessor</annotationProcessor>
</annotationProcessors>
CLI: |
| Key-value options passed to annotation processors. | Gradle:
kapt {
arguments {
arg("room.schemaLocation", "$projectDir/schemas")
}
}
Maven:
<annotationProcessorArgs>
<annotationProcessorArg>room.schemaLocation=/schemas</annotationProcessorArg>
</annotationProcessorArgs>
CLI: |
| Key-value options passed to the Java compiler. | Gradle:
kapt {
javacOptions {
option("-source", "11")
}
}
Maven:
<javacOptions>
<javacOption>-source=11</javacOption>
</javacOptions>
CLI: |
| Enables incremental annotation processing; only reprocesses files affected by changes. | Gradle:
# gradle.properties
kapt.incremental.apt=true
Maven: currently not supported CLI: currently not supported |
Output directory options
Option | Description | How to set up |
|---|---|---|
| Directory where annotation processors generate | Gradle: set automatically to Maven: set automatically to CLI: |
| Directory for | Gradle: managed automatically Maven: managed automatically CLI: |
| Directory for Java stub files generated from Kotlin sources, used as input to annotation processors. | Gradle: managed automatically Maven: managed automatically CLI: |
| Stores state for incremental builds. | Gradle: managed automatically Maven: currently not supported CLI: currently not supported |
Behavioral options
Option | Description | How to set up |
|---|---|---|
| By default, kapt replaces every unknown type (including types for the generated classes) with
| Gradle:
kapt {
correctErrorTypes = true
}
Maven:
<correctErrorTypes>true</correctErrorTypes>
CLI: |
| Includes default parameter initializers as field values in generated stubs.
| Gradle:
kapt {
dumpDefaultParameterValues = true
}
Maven: not available CLI: |
| Maps error messages from stub files back to their original Kotlin source locations.
| Gradle:
kapt {
mapDiagnosticLocations = true
}
Maven:
<mapDiagnosticLocations>true</mapDiagnosticLocations>
CLI: |
| Turns stub generation incompatibilities into errors instead of warnings.
| Gradle:
kapt {
strictMode = true
}
Maven: not available CLI: |
| Removes
| Gradle:
kapt {
stripMetadata = true
}
Maven: not available CLI: |
| Enables verbose kapt logging.
| Gradle:
# gradle.properties
kapt.verbose=true
Maven: currently not supported CLI: currently not supported |
| Promotes info-level kapt messages to warnings.
| Gradle: not directly available Maven: currently not supported CLI: currently not supported |
| Scans the compile classpath for annotation processors. Set to
| Gradle:
kapt {
includeCompileClasspath = false
}
Maven:
<includeCompileClasspath>false</includeCompileClasspath>
CLI: currently not supported |
Diagnostics and statistics options
Option | Description | How to set up |
|---|---|---|
| Prints per-processor execution time to stdout. | Gradle:
kapt {
showProcessorStats = true
}
Maven: not available CLI: |
| Writes processor timing stats to a file. | Gradle: not available Maven: not available CLI: |
| Writes a list of files read by processors to a file, useful for incremental annotation processor debugging. | Gradle: not available Maven: not available CLI: |
| Memory leak detection mode: | Gradle:
kapt {
detectMemoryLeaks = "paranoid"
}
Maven: currently not supported CLI: currently not supported |