Edit Page

Annotation processing with Kotlin

Annotation processors (see JSR 269) are supported in Kotlin with the kapt compiler plugin.

Being short, 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

Apply the kotlin-kapt Gradle plugin:

apply plugin: 'kotlin-kapt'

Or you can apply it using the plugins DSL:

plugins {
    id "org.jetbrains.kotlin.kapt" version "1.1.60"
}

Then add the respective dependencies using the kapt configuration in your dependencies block:

dependencies {
    kapt 'groupId:artifactId:version'
}

If you previously used the Android support for annotation processors, replace usages of the annotationProcessor configuration with kapt. If your project contains Java classes, kapt will also take care of them.

If you use annotation processors for your androidTest or test sources, the respective kapt configurations are named kaptAndroidTest and kaptTest. Note that kaptAndroidTest and kaptTest extends kapt, so you can just provide the kapt dependency and it will be available both for production sources and tests.

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 additional flag to the build.gradle 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>
    </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>

You can find a complete sample project showing the use of Kotlin, Maven and Dagger in the Kotlin examples repository.

Please note that kapt is still 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 many apclasspath 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 in apclasspath.
  • 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.

You can find the complete sample in the kotlin-examples Github repository.

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())
}