Skip to content

kapt 编译器插件

  • 在以下情况下使用 kapt
    • 你使用的是 Maven 项目。
    • 你使用的是 Gradle 项目,但所需的 Java 注解处理器尚不支持 KSP。查看支持的库列表
  • 在以下情况下使用 KSP
    • 你使用的是 Gradle 项目,且所需的 Java 注解处理器支持 KSP。
    • 你想要创建自己的注解处理器。

kapt 编译器插件允许你在 Kotlin 中使用现有的 Java 注解处理器,并同时支持 Maven 和 Gradle。 它从 Kotlin 源代码生成存根文件,然后在这些存根上运行 Java 注解处理器。

这使得在你的 Kotlin 项目中可以为 MapStruct数据绑定 等库启用基于 Java 的注解处理。

IntelliJ 构建系统不支持 kapt。要在 IntelliJ IDEA 中重新运行注解处理,请从 Maven 工具窗口启动构建。

设置插件

你可以为 GradleMaven 配置 kapt 插件,或者在 命令行 中使用。

Gradle

要在 Gradle 中使用 kapt,请按照以下步骤操作:

  1. 在你的构建脚本文件 build.gradle(.kts) 中应用 kapt Gradle 插件:

    kotlin
    plugins {
        kotlin("kapt") version "2.4.10"
    }
    groovy
    plugins {
        id "org.jetbrains.kotlin.kapt" version "2.4.10"
    }
  2. dependencies {} 代码块中使用 kapt 配置添加相应的依赖项:

    kotlin
    dependencies {
        kapt("groupId:artifactId:version")
    }
    groovy
    dependencies {
        kapt 'groupId:artifactId:version'
    }
  3. 如果你之前使用 Android 支持 来处理注解处理器,请将 annotationProcessor 配置的用法替换为 kapt。如果你的项目包含 Java 类,kapt 插件也会处理它们。

    如果你为 androidTesttest 源使用注解处理器,相应的 kapt 配置分别命名为 kaptAndroidTestkaptTest。注意 kaptAndroidTestkaptTest 继承自 kapt,因此你可以提供 kapt 依赖项,它将同时用于生产源码和测试。

Maven

你可以通过为 Kotlin Maven 插件启用 <extensions> 选项 来简化配置,也可以通过 手动配置 来完全控制 kapt 的执行。

自动配置

你可以通过为 Kotlin Maven 插件启用 <extensions> 选项来简化 kapt 配置。在这种情况下,你不需要手动设置带有目标 (goals) 或源目录的 kapt <execution> 部分。

要自动配置 kapt,请在你的 pom.xml 构建文件中为 kotlin-maven-plugin<extensions> 选项设置为 true

xml
<plugin>
    <groupId>org.jetbrains.kotlin</groupId>
    <artifactId>kotlin-maven-plugin</artifactId>
    <version>${kotlin.version}</version>
    <extensions>true</extensions>
    <configuration>
        <annotationProcessorPaths>
            <!-- 在此处指定你的注解处理器 -->
            <annotationProcessorPath>
                <groupId>org.mapstruct</groupId>
                <artifactId>mapstruct-processor</artifactId>
                <version>1.6.3</version>
            </annotationProcessorPath>
        </annotationProcessorPaths>
    </configuration>
</plugin>

有关 <extensions> 选项的更多信息,请参阅自动配置

手动配置

要在你的 Kotlin Maven 项目中手动设置 kapt,请在 compile 执行之前添加来自 kotlin-maven-pluginkapt 目标的执行:

xml
<execution>
    <id>kapt</id>
    <goals>
        <goal>kapt</goal>
    </goals>
    <configuration>
        <sourceDirs>
            <sourceDir>src/main/kotlin</sourceDir>
            <sourceDir>src/main/java</sourceDir>
        </sourceDirs>
        <annotationProcessorPaths>
            <!-- 在此处指定你的注解处理器 -->
            <annotationProcessorPath>
                <groupId>org.mapstruct</groupId>
                <artifactId>mapstruct-processor</artifactId>
                <version>1.6.3</version>
            </annotationProcessorPath>
        </annotationProcessorPaths>
    </configuration>
</execution>

要配置注解处理模式,请在 <configuration> 代码块中设置 aptMode 选项。例如:

xml
<configuration>
   ...
   <aptMode>stubs</aptMode>
</configuration>

CLI

kapt 在 Kotlin 编译器的二进制分发版中作为一个独立的命令行工具可用。

要从命令行运行 kapt,请使用:

bash
kapt <options> <source files>

例如:

bash
kapt -Kapt-mode=stubsAndApt \
  -Kapt-sources=build/kapt/sources \
  -Kapt-classes=build/kapt/classes \
  -Kapt-stubs=build/kapt/stubs \
  -Kapt-classpath=lib/ap.jar \
  -Kapt-classpath=lib/anotherAp.jar \
  src/main/kotlin

配置注解处理器

kapt 提供了控制注解处理器如何被发现、组织和执行的选项,包括管理处理器类路径、从共享配置继承处理器以及保持 javac 特有的处理器处于活跃状态。

有关更多配置选项,例如向注解处理器和 javac 传递选项,请参阅 注解处理器配置

配置处理器类路径和发现

你可以禁用对未包含在 kapt 处理器路径中的注解处理器的发现。 这能有效地从编译类路径中排除不必要的注解处理器。

Gradle

Gradle 利用 编译回避 在重新构建项目时跳过注解处理,从而缩短使用 kapt 的增量构建时间。特别是,在以下情况下会跳过注解处理:

  • 项目的源文件未更改。
  • 依赖项中的更改是 ABI 兼容的。例如,只有函数体发生更改时。

然而,对于在编译类路径上发现的注解处理器,无法使用编译回避,因为即使处理器的 ABI 保持不变,其内部实现的更改也需要运行注解处理任务。

这就是为什么我们不建议使用来自编译类路径的注解处理器。要将这些处理器从 kapt 处理中排除,请在你的 gradle.properties 文件中添加 kapt.include.compile.classpath 属性:

none
# gradle.properties
kapt.include.compile.classpath=false

当该选项设置为 false 时,未包含在处理器路径(即 kapt* 配置)中的注解处理器依赖项将从 kapt 处理中排除。

Maven

要排除未包含在 kapt 处理器路径中的注解处理器,请在 kapt 插件的 <execution> 部分将 includeCompileClasspath 选项设置为 false

xml
<execution>
    <id>kapt</id>
    <goals>
        <goal>kapt</goal>
    </goals>
    <configuration>
        <includeCompileClasspath>false</includeCompileClasspath>
        <sourceDirs>...</sourceDirs>
        <annotationProcessorPaths>...</annotationProcessorPaths>
    </configuration>
</execution>

或者,你可以在 pom.xml<properties> 部分使用 kapt.include.compile.classpath 属性:

xml
<properties>
    <kapt.include.compile.classpath>false</kapt.include.compile.classpath>
</properties>

当该选项设置为 false 时,未包含在 <annotationProcessorPaths> 部分的注解处理器将从 kapt 处理中排除。

如果未设置 includeCompileClasspath 选项,且 kapt 在编译类路径上检测到了未在处理器路径中明确定义的注解处理器,你将看到一条弃用警告:

none
[WARNING] Annotation processors discovery from compile classpath is deprecated.
Set 'kapt.include.compile.classpath=false' to disable discovery.

要查看未在 kapt 类路径上出现的注解处理器列表,请使用 --info 日志级别选项运行构建。

从超配置中继承注解处理器

你可以在一个单独的 Gradle 配置中定义一组通用的注解处理器作为超配置,并在子项目中专门针对 kapt 的配置进一步扩展它。

例如,对于使用 MapStruct 的子项目,在你的 build.gradle(.kts) 文件中使用以下配置:

kotlin
val commonAnnotationProcessors by configurations.creating
configurations.named("kapt") { extendsFrom(commonAnnotationProcessors) }

dependencies {
    implementation("org.mapstruct:mapstruct:1.6.3")
    commonAnnotationProcessors("org.mapstruct:mapstruct-processor:1.6.3")
}

在此示例中,commonAnnotationProcessors Gradle 配置是你希望在所有项目中使用的通用注解处理超配置。你使用 extendsFrom() 方法将 commonAnnotationProcessors 添加为超配置。kapt 识别到 commonAnnotationProcessors Gradle 配置对 MapStruct 注解处理器有依赖。因此,kapt 在其注解处理配置中包含了 MapStruct 注解处理器。

保留 Java 编译器的注解处理器

默认情况下,kapt 运行所有注解处理器并禁用 javac 的注解处理。 然而,你可能需要 javac 运行一些注解处理器,例如 Lombok

在 Gradle 构建文件中,使用选项 keepJavacAnnotationProcessors

groovy
kapt {
    keepJavacAnnotationProcessors = true
}

如果你使用 Maven,则需要显式配置该插件。 参见这个 Lombok 编译器插件设置示例

优化 kapt 构建

kapt 提供了几种特定于 Gradle 的策略来减少注解处理时间,包括并行运行任务、利用构建缓存、缓存处理器类加载器以及使用增量注解处理。

有关影响构建行为的其他选项(如错误类型修正、存根元数据剥离和编译类路径扫描),请参阅 行为选项

并行运行 kapt 任务

kapt 使用 Gradle Worker API 来运行注解处理任务。使用 Worker API 让 Gradle 能够并行运行来自单个项目的独立注解处理任务,在某些情况下,这会显著减少执行时间。

如果你在 Kotlin Gradle 插件中设置了自定义 JDK 版本,kapt 任务工作程序仅使用 processIsolation() 模式。

如果你想为 kapt 工作进程提供额外的 JVM 实参,请使用 KaptWithoutKotlincTask 的输入 kaptProcessJvmArgs

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

安全使用 Gradle 构建缓存

kapt 注解处理任务默认在 Gradle 中缓存。然而,注解处理器可以运行任意代码。这可能导致任务输入到输出的不必要转换,或者访问和修改 Gradle 无法跟踪的文件。

如果构建中使用的注解处理器无法被正确缓存,你可以禁用缓存以防止 kapt 任务出现误报的缓存命中。为此,请在构建脚本中使用 useBuildCache 属性:

groovy
kapt {
    useBuildCache = false
}
Experimental

为注解处理器的类加载器启用缓存

如果你连续运行多个 Gradle 任务,为注解处理器的类加载器启用缓存有助于 kapt 运行得更快。

要启用此功能,请在你的 gradle.properties 文件中使用以下属性:

none
# gradle.properties
#
# 任何正值都会启用缓存
# 使用与使用 kapt 的模块数量相同的值
kapt.classloaders.cache.size=5

# 禁用此项以使缓存工作
kapt.include.compile.classpath=false

如果你在注解处理器的缓存方面遇到任何问题,请为它们禁用缓存:

none
# 指定注解处理器的全名以禁用它们的缓存
kapt.classloaders.cache.disableForProcessors=[annotation processors full names]

如果你遇到该功能的任何问题,我们非常感谢你在 YouTrack 中提供反馈。

使用增量注解处理

配合 Gradle 使用时,kapt 默认支持增量注解处理,以便仅重新处理更改的文件。

目前,仅在以下情况下,增量注解处理才能工作:

  • 启用了增量编译
  • 构建中使用的所有注解处理器都是增量式的。

要禁用增量注解处理,请在你的 gradle.properties 文件中添加这一行:

none
kapt.incremental.apt=false

目前 Maven 或命令行尚不支持 kapt 的增量注解处理。

分析性能

kapt 提供了内置诊断功能,可帮助你了解注解处理性能,包括按处理器生成的执行时间报告和生成的文件计数,以识别未使用的处理器。

有关更多诊断选项,例如用于调试增量处理的文件读取历史记录和内存泄漏检测,请参阅 诊断与统计选项

衡量注解处理器的性能

要获取有关注解处理器执行情况的性能统计信息,请使用 showProcessorStats 选项。示例输出如下:

text
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

你可以使用 dumpProcessorStats 选项将此报告转储到文件中。例如,以下命令行命令运行 kapt 并将统计信息转储到 ap-perf-report.file 文件中:

bash
kapt -Kapt-mode=stubsAndApt \
  -Kapt-classpath=processor/build/libs/processor.jar \
  -Kapt-dump-processor-stats=ap-perf-report.file \
  sample/src/main/

统计生成的文件数量

kapt 插件可以报告每个注解处理器生成文件数量的统计信息。

这有助于跟踪构建中是否包含任何未使用的注解处理器。你可以使用生成的报告找到触发不必要注解处理器的模块,并更新这些模块以避免这种情况。

要启用统计报告:

  1. 在你的 Gradle 构建文件中,将 showProcessorStats 选项设置为 true

    kotlin
    // build.gradle(.kts)
    kapt {
        showProcessorStats = true
    }
  2. 在你的 gradle.properties 文件中,将 verbose 编译器选项设置为 true

    # gradle.properties
    kapt.verbose=true

统计信息以 info 级别出现在日志中。你可以看到 Annotation processor stats: 行,随后是每个注解处理器执行时间的统计信息。在这些行之后是 Generated files report: 行,随后是每个注解处理器生成文件数量的统计信息。例如:

text
[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

目前 Maven 或命令行尚不支持通过 showProcessorStatsverbose 编译器选项统计生成的文件数量。

生成 Kotlin 源码

kapt 可以生成 Kotlin 源码。为此,请将生成的 Kotlin 源码文件写入由 processingEnv.options["kapt.kotlin.generated"] 指定的目录。这些 Kotlin 源码文件随后将与主源码一起编译。

kapt 不支持对生成的 Kotlin 文件进行多轮注解处理。

编译器选项

注解处理器配置

选项描述如何设置
aptMode 控制 kapt 工作流阶段的执行:
  • stubsAndApt 生成存根并运行注解处理(默认)
  • stubs 仅从 Kotlin 生成 Java 存根
  • apt 仅运行注解处理器(假设存根已存在)

Gradle: 无法直接设置;Gradle 将存根生成和 apt 作为独立任务运行

Maven:

xml

CLI: -Kapt-mode=stubsAndApt

classpath发现注解处理器的类路径条目。

Gradle:

kotlin

Maven:

xml

CLI: -Kapt-classpath=lib/my-processor.jar

processors要运行的处理器的完全限定类名(以逗号分隔),绕过发现机制。

Gradle:

kotlin

Maven:

xml

CLI: -Kapt-processors=com.example.MyProcessor

apOption传递给注解处理器的键值对选项。

Gradle:

kotlin

Maven:

xml

CLI: -Kapt-options:room.schemaLocation=/schemas

javacOption传递给 Java 编译器的键值对选项。

Gradle:

kotlin

Maven:

xml

CLI: -Kapt-javac-option:-source=11

processIncrementally启用增量注解处理;仅重新处理受更改影响的文件。

Gradle:

kotlin

Maven: 目前不支持

CLI: 目前不支持

输出目录选项

选项描述如何设置
sources注解处理器生成 .java 源码文件的目录。

Gradle: 自动设置为 build/generated/source/kapt/main

Maven: 自动设置为 target/generated-sources/kapt/

CLI: -Kapt-sources=build/kapt/sources

classes从生成的源码编译而来的 .class 文件的目录。

Gradle: 自动管理

Maven: 自动管理

CLI: -Kapt-classes=build/kapt/classes

stubs从 Kotlin 源码生成的 Java 存根文件的目录,用作注解处理器的输入。

Gradle: 自动管理

Maven: 自动管理

CLI: -Kapt-stubs=build/kapt/stubs

incrementalData存储增量构建的状态。

Gradle: 自动管理

Maven: 目前不支持

CLI: 目前不支持

行为选项

选项描述如何设置
correctErrorTypes 默认情况下,kapt 会将每个未知类型(包括生成的类的类型)替换为 NonExistentClass。 你可以启用存根中的错误类型推断,以将未解析的错误类型替换为来自生成的源码中的类型。

默认为 false

Gradle:

kotlin

Maven:

xml

CLI: -Kapt-correct-error-types=true

dumpDefaultParameterValues 在生成的存根中将默认形参初始值设定项作为字段值包含在内。

默认为 false

Gradle:

kotlin

Maven: 不可用

CLI: -Kapt-dump-default-parameter-values=true

mapDiagnosticLocations 将存根文件中的错误消息映射回其原始的 Kotlin 源码位置。

默认为 false

Gradle:

kotlin

Maven:

xml

CLI: -Kapt-map-diagnostic-locations=true

strict 将存根生成中的不兼容问题转换为错误而非警告。

默认为 false

Gradle:

kotlin

Maven: 不可用

CLI: -Kapt-strict=true

stripMetadata 从生成的存根中移除 @kotlin.Metadata 注解,从而减小存根大小并向处理器隐藏 Kotlin 特有的信息。

默认为 false

Gradle:

kotlin

Maven: 不可用

CLI: -Kapt-strip-metadata=true

verbose 启用详细的 kapt 日志记录。

默认为 false

Gradle:

kotlin

Maven: 目前不支持

CLI: 目前不支持

infoAsWarnings 将 info 级别的 kapt 消息提升为警告。

默认为 false

Gradle: 无法直接设置

Maven: 目前不支持

CLI: 目前不支持

includeCompileClasspath 扫描编译类路径以查找注解处理器。为了可复现性,建议将其设置为 false

默认为 true

Gradle:

kotlin

Maven:

xml

CLI: 目前不支持

诊断与统计选项

选项描述如何设置
showProcessorStats将每个处理器的执行时间打印到标准输出 (stdout)。

Gradle:

kotlin

Maven: 不可用

CLI: -Kapt-show-processor-stats=true

dumpProcessorStats将处理器时间统计信息写入文件。

Gradle: 不可用

Maven: 不可用

CLI: -Kapt-dump-processor-stats=build/kapt-stats.txt

dumpFileReadHistory将处理器读取的文件列表写入文件,对于调试增量注解处理器非常有用。

Gradle: 不可用

Maven: 不可用

CLI: -Kapt-dump-file-read-history=build/kapt-reads.txt

detectMemoryLeaks内存泄漏检测模式:nonedefaultparanoid

Gradle:

kotlin

Maven: 目前不支持

CLI: 目前不支持

下一步