12.2.3 kapt 编译器插件
10 分钟阅读
12.2.3 kapt 编译器插件
kapt 编译器插件让你可以在 Kotlin 中使用现有的 Java 注解处理器,并同时支持 Maven 和 Gradle。它会根据 Kotlin 源码生成桩文件,然后在这些桩文件上运行 Java 注解处理器。
这使你可以在 Kotlin 项目中对 MapStruct 和 Data Binding 等库使用基于 Java 的注解处理。
警告: IntelliJ 构建系统不支持 kapt。要在 IntelliJ IDEA 中重新运行注解处理,请从 Maven 工具窗口启动构建。
设置插件
你可以为 Gradle、Maven 配置 kapt 插件,也可以从命令行使用它。
Gradle
要在 Gradle 中使用 kapt,请按以下步骤操作:
- 在构建脚本文件
build.gradle(.kts)中应用kaptGradle 插件:
Kotlin
| |
Groovy
| |
- 在
dependencies {}块中使用kapt配置添加相应的依赖:
Kotlin
| |
Groovy
| |
- 如果你之前使用 Android 的注解处理器支持,请把
annotationProcessor配置的用法替换为kapt。如果你的项目包含 Java 类,kapt 插件也会处理它们。
如果你为 androidTest 或 test 源码使用注解处理器,相应的 kapt 配置名为 kaptAndroidTest 和 kaptTest。请注意,kaptAndroidTest 和 kaptTest 都扩展自 kapt,因此你只需提供 kapt 依赖,它就会同时用于生产源码和测试。
Maven
你可以使用 <extensions> 选项来简化 kapt 的设置,也可以手动设置,以完全掌控 kapt 的执行。
自动配置
你可以通过为 Kotlin Maven 插件启用 <extensions> 选项来简化 kapt 配置。在这种情况下,你无需手动设置包含目标或源目录的 kapt <execution> 部分。
要自动配置 kapt,请在 pom.xml 构建文件中把 kotlin-maven-plugin 的 <extensions> 选项设置为 true:
| |
关于 <extensions> 选项的更多信息,请参阅自动配置。
手动配置
要在 Kotlin Maven 项目中手动设置 kapt,请在 compile 执行之前添加 kotlin-maven-plugin 的 kapt 目标执行:
| |
要配置注解处理模式,请在 <configuration> 块中设置 aptMode 选项。例如:
| |
CLI
kapt 作为独立的 CLI 工具包含在 Kotlin 编译器的二进制发行版中。
要从命令行运行 kapt,请使用:
| |
例如:
| |
- 查看 kapt 特有的编译器选项的完整列表。
- 你也可以传入所有有效的 Kotlin 编译器选项。运行
kotlinc -help可以查看它们。
配置注解处理器
kapt 提供了若干选项来控制注解处理器如何被发现、组织和执行,包括管理处理器 classpath、从共享配置继承处理器,以及保持 javac 专用处理器处于活动状态。
关于更多配置选项,例如向注解处理器和 javac 传递选项,请参阅注解处理器配置。
配置处理器 classpath 与发现
你可以禁止发现未包含在 kapt 处理器路径中的注解处理器。这样就能把不必要的注解处理器从编译 classpath 中排除。
Gradle
Gradle 使用跳过编译在项目重新构建时跳过注解处理,从而改善 kapt 的增量构建时间。具体来说,以下情况会跳过注解处理:
- 项目的源文件没有变化。
- 依赖中的变化是 ABI 兼容的。例如,只有函数体发生变化。
然而,对于在编译 classpath 上发现的注解处理器,无法使用跳过编译,因为它们内部实现的变化需要运行注解处理任务,即使这些处理器的 ABI 没有变化。
因此我们不建议使用来自编译 classpath 的注解处理器。要把这些处理器从 kapt 处理中排除,请在 gradle.properties 文件中添加 kapt.include.compile.classpath 属性:
# gradle.properties
kapt.include.compile.classpath=false
该选项设置为 false 后,未包含在处理器路径(kapt* 配置)中的注解处理器依赖会被排除在 kapt 处理之外。
Maven
要排除未包含在 kapt 处理器路径中的注解处理器,请在 kapt 插件的 <execution> 部分中把 includeCompileClasspath 选项设置为 false:
| |
或者,你也可以在 pom.xml 的 <properties> 部分使用 kapt.include.compile.classpath 属性:
| |
该选项设置为 false 后,未包含在 <annotationProcessorPaths> 部分中的注解处理器会被排除在 kapt 处理之外。
如果没有设置 includeCompileClasspath 选项,而 kapt 在编译 classpath 上检测到未在处理器路径中显式定义的注解处理器,你会看到一条弃用警告:
[WARNING] Annotation processors discovery from compile classpath is deprecated.
Set 'kapt.include.compile.classpath=false' to disable discovery.
提示: 要查看未包含在 kapt classpath 中的注解处理器列表,请使用
--info日志级别选项运行构建。
从父配置继承注解处理器
你可以在一个单独的 Gradle 配置中定义一整套公共注解处理器作为父配置,并在各子项目中专用于 kapt 的配置里进一步扩展它。
例如,对于使用 MapStruct 的子项目,在你的 build.gradle(.kts) 文件中使用以下配置:
| |
在这个例子中,commonAnnotationProcessors Gradle 配置是你希望用于所有项目的注解处理公共父配置。你使用 extendsFrom() 方法把 commonAnnotationProcessors 添加为父配置。kapt 看到 commonAnnotationProcessors Gradle 配置中有对 MapStruct 注解处理器的依赖,因此会把该处理器包含进自己的注解处理配置中。
保留 Java 编译器的注解处理器
默认情况下,kapt 会运行所有注解处理器,并禁用 javac 的注解处理。不过,你可能需要 javac 来运行某些注解处理器,例如 Lombok。
在 Gradle 构建文件中,使用 keepJavacAnnotationProcessors 选项:
| |
如果你使用 Maven,请显式配置插件。请参阅这个设置 Lombok 编译器插件的示例。
优化 kapt 构建
kapt 提供了若干 Gradle 特有的策略来减少注解处理时间,包括并行运行任务、利用构建缓存、缓存处理器类加载器以及使用增量注解处理。
关于影响构建行为的更多选项,例如错误类型修正、桩元数据剥离以及编译 classpath 扫描,请参阅行为选项。
并行运行 kapt 任务
kapt 使用 Gradle Worker API来运行注解处理任务。使用 Worker API 让 Gradle 可以并行运行单个项目中的独立注解处理任务,在某些情况下能显著缩短执行时间。
如果你在 Kotlin Gradle 插件中设置了自定义 JDK 版本,kapt 任务工作进程只会使用 processIsolation() 模式。
如果你想为 kapt 工作进程提供额外的 JVM 参数,请使用 KaptWithoutKotlincTask 的输入 kaptProcessJvmArgs:
Kotlin
| |
Groovy
| |
安全地使用 Gradle 构建缓存
Gradle 会默认缓存 kapt 注解处理任务。然而,注解处理器可以运行任意代码。这可能导致把任务输入不必要地转换为输出,或者访问和修改 Gradle 无法跟踪的文件。
当构建中使用的注解处理器无法被正确缓存时,你可以禁用缓存,以避免 kapt 任务出现误命中。为此,请在构建脚本中使用 useBuildCache 属性:
| |
缓存注解处理器的类加载器
实验性 - 通用
如果你连续运行许多 Gradle 任务,缓存注解处理器的类加载器可以帮助 kapt 运行得更快。
要启用该特性,请在 gradle.properties 文件中使用以下属性:
# gradle.properties
#
# Any positive value enables 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
如果你在注解处理器缓存方面遇到任何问题,请为它们禁用缓存:
# Specify annotation processors' full names to disable caching for them
kapt.classloaders.cache.disableForProcessors=[annotation processors full names]
注意: 如果你在使用该特性时遇到任何问题,我们非常欢迎你在 YouTrack 上提供反馈。
使用增量注解处理
在 Gradle 中,kapt 默认支持增量注解处理,因此只会重新处理发生变化的文件。
目前,增量注解处理仅在以下情况有效:
- 增量编译已启用。
- 构建中的所有注解处理器都是增量的。
要禁用增量注解处理,请在 gradle.properties 文件中添加以下行:
kapt.incremental.apt=false
注意: 目前,kapt 的增量注解处理在 Maven 或 CLI 中不受支持。
分析性能
kapt 提供了内置的诊断功能,帮助你了解注解处理的性能,包括每个处理器的执行时间报告和生成文件数量,以便识别未使用的处理器。
关于更多诊断选项,例如用于调试增量处理的文件读取历史和内存泄漏检测,请参阅诊断与统计选项。
测量注解处理器的性能
要获取注解处理器执行的性能统计信息,请使用 showProcessorStats 选项。示例输出如下:
| |
你可以使用 dumpProcessorStats 选项把该报告导出到文件。例如,下面的 CLI 命令运行 kapt 并把统计信息导出到 ap-perf-report.file 文件:
| |
跟踪生成文件的数量
kapt 插件可以报告每个注解处理器生成文件数量的统计信息。
这有助于跟踪构建中是否包含未使用的注解处理器。你可以利用生成的报告找出触发不必要注解处理器的模块,并更新这些模块以避免出现这种情况。
要启用统计信息报告:
- 在你的 Gradle 构建文件中,把
showProcessorStats选项设置为true:
| |
- 在你的
gradle.properties文件中,把verbose编译器选项设置为true:
# gradle.properties
kapt.verbose=true
统计信息会以 info 级别出现在日志中。你可以看到 Annotation processor stats: 行,其后是每个注解处理器执行时间的统计信息。在这些行之后是 Generated files report: 行,其后是每个注解处理器生成文件数量的统计信息。例如:
| |
注意: 目前,使用
showProcessorStats和verbose编译器选项跟踪生成文件数量在 Maven 或 CLI 中不受支持。
生成 Kotlin 源码
kapt 可以生成 Kotlin 源码。为此,请使用 processingEnv.options["kapt.kotlin.generated"] 把生成的 Kotlin 源文件写入指定目录。随后这些 Kotlin 源文件会与主源码一起编译。
注意: kapt 不支持对生成的 Kotlin 文件进行多轮注解处理。
编译器选项
注解处理器配置
| 选项 | 说明 | 如何设置 |
|---|---|---|
aptMode | 控制 kapt 工作流各阶段的执行: stubsAndApt 生成桩并运行注解处理(默认) stubs 只从 Kotlin 生成 Java 桩 apt 只运行注解处理器(假定桩已存在) | Gradle: 不能直接使用;Gradle 把生成桩和 apt 作为单独任务运行 Maven: stubsAndApt ]]> CLI: -Kapt-mode=stubsAndApt |
classpath | 用于发现注解处理器的 classpath 条目。 | Gradle: dependencies { kapt(“com.example:processor:1.0”) } Maven: -Kapt-classpath=lib/my-processor.jar |
processors | 要运行的处理器完全限定类名,以逗号分隔,绕过自动发现。 | Gradle: kapt { annotationProcessor(“com.example.MyProcessor”) } Maven: -Kapt-processors=com.example.MyProcessor |
apOption | 传递给注解处理器的键值选项。 | Gradle: kapt { arguments { arg(“room.schemaLocation”, “$projectDir/schemas”) } } Maven: -Kapt-options:room.schemaLocation=/schemas |
javacOption | 传递给 Java 编译器的键值选项。 | Gradle: kapt { javacOptions { option("-source", “11”) } } Maven: -Kapt-javac-option:-source=11 |
processIncrementally | 启用增量注解处理;只会重新处理受变更影响的文件。 | Gradle: # gradle.properties kapt.incremental.apt=true 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: kapt { correctErrorTypes = true } Maven: true ]]> CLI: -Kapt-correct-error-types=true |
dumpDefaultParameterValues | 在生成的桩中把默认参数初始化器作为字段值包含进来。 默认为 false | Gradle: kapt { dumpDefaultParameterValues = true } Maven: 不可用 CLI: -Kapt-dump-default-parameter-values=true |
mapDiagnosticLocations | 把桩文件中的错误消息映射回它们原本的 Kotlin 源码位置。 默认为 false | Gradle: kapt { mapDiagnosticLocations = true } Maven: true ]]> CLI: -Kapt-map-diagnostic-locations=true |
strict | 把桩生成中的不兼容情况从警告变为错误。 默认为 false | Gradle: kapt { strictMode = true } Maven: 不可用 CLI: -Kapt-strict=true |
stripMetadata | 从生成的桩中移除 @kotlin.Metadata 注解,从而减小桩体积,并向处理器隐藏 Kotlin 特有的信息。 默认为 false | Gradle: kapt { stripMetadata = true } Maven: 不可用 CLI: -Kapt-strip-metadata=true |
verbose | 启用 kapt 的详细日志。 默认为 false | Gradle: # gradle.properties kapt.verbose=true Maven: 目前不支持 CLI: 目前不支持 |
infoAsWarnings | 把 info 级别的 kapt 消息提升为警告。 默认为 false | Gradle: 不能直接使用 Maven: 目前不支持 CLI: 目前不支持 |
includeCompileClasspath | 在编译 classpath 中扫描注解处理器。为实现可复现性请设置为 false。 默认为 true | Gradle: kapt { includeCompileClasspath = false } Maven: false ]]> CLI: 目前不支持 |
诊断与统计选项
| 选项 | 说明 | 如何设置 |
|---|---|---|
showProcessorStats | 把每个处理器的执行时间打印到标准输出。 | Gradle: kapt { showProcessorStats = true } 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 | 内存泄漏检测模式:none、default 或 paranoid。 | Gradle: kapt { detectMemoryLeaks = “paranoid” } Maven: 目前不支持 CLI: 目前不支持 |