- kapt 编译器插件
- Using in Gradle
- Annotation processor arguments
- Gradle 构建缓存支持
- Improving the speed of builds that use kapt
- Compile avoidance for kapt
- Incremental annotation processing
- Java compiler options
- Non-existent type correction
- Using in Maven
- Using in IntelliJ build system
- Using in CLI
- Generating Kotlin sources
- AP/Javac options encoding
- Keeping Java compiler’s annotation processors
kapt 编译器插件
kapt is in maintenance mode. We are keeping it up-to-date with recent Kotlin and Java releases but have no plans to implement new features. Please use the Kotlin Symbol Processing API (KSP) for annotation processing. See the list of libraries supported by KSP.
Annotation processors (see JSR 269) are supported in Kotlin with the kapt compiler plugin.
In a nutshell, you can use libraries such as Dagger or Data Binding in your Kotlin projects.
Please read below about how to apply the kapt plugin to your Gradle/Maven build.
Using in Gradle
Follow these steps:
- Apply the
kotlin-kapt
Gradle plugin:
【Kotlin】
plugins {
kotlin("kapt") version "1.9.10"
}
【Groovy】
plugins {
id "org.jetbrains.kotlin.kapt" version "1.9.10"
}
- Add the respective dependencies using the
kapt
configuration in yourdependencies
block:
【Kotlin】
dependencies {
kapt("groupId:artifactId:version")
}
【Groovy】
dependencies {
kapt 'groupId:artifactId:version'
}
If you previously used the Android support for annotation processors, replace usages of the
annotationProcessor
configuration withkapt
. If your project contains Java classes,kapt
will also take care of them.If you use annotation processors for your
androidTest
ortest
sources, the respectivekapt
configurations are namedkaptAndroidTest
andkaptTest
. Note thatkaptAndroidTest
andkaptTest
extendskapt
, so you can just provide thekapt
dependency and it will be available both for production sources and tests.
Annotation processor arguments
Use arguments {}
block to pass arguments to annotation processors:
kapt {
arguments {
arg("key", "value")
}
}
Gradle 构建缓存支持
The kapt annotation processing tasks are cached in Gradle by default. However, annotation processors run arbitrary code that may not necessarily transform the task inputs into the outputs, might access and modify the files that are not tracked by Gradle etc. If the annotation processors used in the build cannot be properly cached, it is possible to disable caching for kapt entirely by adding the following lines to the build script, in order to avoid false-positive cache hits for the kapt tasks:
kapt {
useBuildCache = false
}
Improving the speed of builds that use kapt
Running kapt tasks in parallel
To improve the speed of builds that use kapt, you can enable the Gradle Worker API for kapt 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.
When you use the custom JDK home feature in the Kotlin Gradle plugin, kapt task workers use only process isolation mode. Note that the kapt.workers.isolation
property is ignored.
If you want to provide additional JVM arguments for a kapt worker process, use the input kaptProcessJvmArgs
of the KaptWithoutKotlincTask
:
【Kotlin】
tasks.withType<org.jetbrains.kotlin.gradle.internal.KaptWithoutKotlincTask>()
.configureEach {
kaptProcessJvmArgs.add("-Xmx512m")
}
【Groovy】
tasks.withType(org.jetbrains.kotlin.gradle.internal.KaptWithoutKotlincTask.class)
.configureEach {
kaptProcessJvmArgs.add('-Xmx512m')
}
Caching for annotation processors’ classloaders
在 kapt 中缓存注解处理器的类加载器 is Experimental. It may be dropped or changed at any time. Use it only for evaluation purposes. We would appreciate your feedback on it in YouTrack.
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:
# positive value will enable caching
# use the same value as the number of modules that use kapt
kapt.classloaders.cache.size=5
# disable for caching to work
kapt.include.compile.classpath=false
If you run into any problems with caching for annotation processors, disable caching for them:
# specify annotation processors' full names to disable caching for them
kapt.classloaders.cache.disableForProcessors=[annotation processors full names]
Measuring performance of annotation processors
Get a performance statistics on the annotation processors execution using the -Kapt-show-processor-timings
plugin option. An example output:
Kapt Annotation Processing performance report:
com.example.processor.TestingProcessor: total: 133 ms, init: 36 ms, 2 round(s): 97 ms, 0 ms
com.example.processor.AnotherProcessor: total: 100 ms, init: 6 ms, 1 round(s): 93 ms
You can dump this report into a file with the plugin option -Kapt-dump-processor-timings (org.jetbrains.kotlin.kapt3:dumpProcessorTimings). The following command will run kapt and dump the statistics to the ap-perf-report.file
file:
kotlinc -cp $MY_CLASSPATH \
-Xplugin=kotlin-annotation-processing-SNAPSHOT.jar -P \
plugin:org.jetbrains.kotlin.kapt3:aptMode=stubsAndApt,\
plugin:org.jetbrains.kotlin.kapt3:apclasspath=processor/build/libs/processor.jar,\
plugin:org.jetbrains.kotlin.kapt3:dumpProcessorTimings=ap-perf-report.file \
-Xplugin=$JAVA_HOME/lib/tools.jar \
-d cli-tests/out \
-no-jdk -no-reflect -no-stdlib -verbose \
sample/src/main/
Measuring the number of files generated with annotation processors
The kotlin-kapt
Gradle plugin can report statistics on the number of generated files for each annotation processor.
This is useful to track if there are unused annotation processors as a part of the build. You can use the generated report to find modules that trigger unnecessary annotation processors and update the modules to prevent that.
Enable the statistics in two steps:
Set the
showProcessorStats
flag totrue
in yourbuild.gradle(.kts)
:kapt {
showProcessorStats = true
}
Set the
kapt.verbose
Gradle property totrue
in yourgradle.properties
:kapt.verbose=true
You can also enable verbose output via the command line option verbose.
The statistics will appear in the logs with the info
level. You’ll see the Annotation processor stats:
line followed by statistics on the execution time of each annotation processor. After these lines, there will be the Generated files report:
line followed by statistics on the number of generated files for each annotation processor. For example:
[INFO] Annotation processor stats:
[INFO] org.mapstruct.ap.MappingProcessor: total: 290 ms, init: 1 ms, 3 round(s): 289 ms, 0 ms, 0 ms
[INFO] Generated files report:
[INFO] org.mapstruct.ap.MappingProcessor: total sources: 2, sources per round: 2, 0, 0
Compile avoidance for kapt
To improve the times of incremental builds with kapt, it can use the Gradle compile avoidance. With compile avoidance enabled, Gradle can skip annotation processing when rebuilding a project. Particularly, annotation processing is skipped when:
- The project’s source files are unchanged.
- The changes in dependencies are ABI compatible. For example, the only changes are in method bodies.
However, compile avoidance can’t be used for annotation processors discovered in the compile classpath since any changes in them require running the annotation processing tasks.
To run kapt with compile avoidance:
- Add the annotation processor dependencies to the
kapt*
configurations manually as described above. - Turn off the discovery of annotation processors in the compile classpath by adding this line to your
gradle.properties
file:
kapt.include.compile.classpath=false
Incremental annotation processing
kapt supports incremental annotation processing that is enabled by default. Currently, annotation processing can be incremental only if all annotation processors being used are incremental.
To disable incremental annotation processing, add this line to your gradle.properties
file:
kapt.incremental.apt=false
Note that incremental annotation processing requires incremental compilation to be enabled as well.
Java compiler options
kapt uses Java compiler to run annotation processors.
Here is how you can pass arbitrary options to javac:
kapt {
javacOptions {
// Increase the max count of errors from annotation processors.
// Default is 100.
option("-Xmaxerrs", 500)
}
}
Non-existent type correction
Some annotation processors (such as AutoFactory
) rely on precise types in declaration signatures. By default, kapt replaces every unknown type (including types for the generated classes) to NonExistentClass
, but you can change this behavior. Add the option to the build.gradle(.kts)
file to enable error type inferring in stubs:
kapt {
correctErrorTypes = true
}
Using in Maven
Add an execution of the kapt
goal from kotlin-maven-plugin before compile
:
<execution>
<id>kapt</id>
<goals>
<goal>kapt</goal> <!-- You can skip the <goals> element
if you enable extensions for the plugin -->
</goals>
<configuration>
<sourceDirs>
<sourceDir>src/main/kotlin</sourceDir>
<sourceDir>src/main/java</sourceDir>
</sourceDirs>
<annotationProcessorPaths>
<!-- Specify your annotation processors here -->
<annotationProcessorPath>
<groupId>com.google.dagger</groupId>
<artifactId>dagger-compiler</artifactId>
<version>2.9</version>
</annotationProcessorPath>
</annotationProcessorPaths>
</configuration>
</execution>
To configure the level of annotation processing, set one of the following as the aptMode
in the <configuration>
block:
stubs
– only generate stubs needed for annotation processing.apt
– only run annotation processing.stubsAndApt
– (default) generate stubs and run annotation processing.
For example:
<configuration>
...
<aptMode>stubs</aptMode>
</configuration>
Using in IntelliJ build system
kapt is not supported for IntelliJ IDEA’s own build system. Launch the build from the “Maven Projects” toolbar whenever you want to re-run the annotation processing.
Using in CLI
kapt compiler plugin is available in the binary distribution of the Kotlin compiler.
You can attach the plugin by providing the path to its JAR file using the Xplugin
kotlinc option:
-Xplugin=$KOTLIN_HOME/lib/kotlin-annotation-processing.jar
Here is a list of the available options:
sources
(required): An output path for the generated files.classes
(required): An output path for the generated class files and resources.stubs
(required): An output path for the stub files. In other words, some temporary directory.incrementalData
: An output path for the binary stubs.apclasspath
(repeatable): A path to the annotation processor JAR. Pass as manyapclasspath
options as many JARs you have.apoptions
: A base64-encoded list of the annotation processor options. See AP/javac options encoding for more information.javacArguments
: A base64-encoded list of the options passed to javac. See AP/javac options encoding for more information.processors
: A comma-specified list of annotation processor qualified class names. If specified, kapt does not try to find annotation processors inapclasspath
.verbose
: Enable verbose output.aptMode
(required)stubs
– only generate stubs needed for annotation processing.apt
– only run annotation processing.stubsAndApt
– generate stubs and run annotation processing.
correctErrorTypes
: See below. Disabled by default.
The plugin option format is: -P plugin:<plugin id>:<key>=<value>
. Options can be repeated.
An example:
-P plugin:org.jetbrains.kotlin.kapt3:sources=build/kapt/sources
-P plugin:org.jetbrains.kotlin.kapt3:classes=build/kapt/classes
-P plugin:org.jetbrains.kotlin.kapt3:stubs=build/kapt/stubs
-P plugin:org.jetbrains.kotlin.kapt3:apclasspath=lib/ap.jar
-P plugin:org.jetbrains.kotlin.kapt3:apclasspath=lib/anotherAp.jar
-P plugin:org.jetbrains.kotlin.kapt3:correctErrorTypes=true
Generating Kotlin sources
kapt can generate Kotlin sources. Just write the generated Kotlin source files to the directory specified by processingEnv.options["kapt.kotlin.generated"]
, and these files will be compiled together with the main sources.
Note that kapt does not support multiple rounds for the generated Kotlin files.
AP/Javac options encoding
apoptions
and javacArguments
CLI options accept an encoded map of options.
Here is how you can encode options by yourself:
fun encodeList(options: Map<String, String>): String {
val os = ByteArrayOutputStream()
val oos = ObjectOutputStream(os)
oos.writeInt(options.size)
for ((key, value) in options.entries) {
oos.writeUTF(key)
oos.writeUTF(value)
}
oos.flush()
return Base64.getEncoder().encodeToString(os.toByteArray())
}
Keeping Java compiler’s annotation processors
By default, kapt runs all annotation processors and disables annotation processing by javac. However, you may need some of javac’s annotation processors working (for example, Lombok).
In the Gradle build file, use the option keepJavacAnnotationProcessors
:
kapt {
keepJavacAnnotationProcessors = true
}
If you use Maven, you need to specify concrete plugin settings. See this example of settings for the Lombok compiler plugin.