gradle init --type kotlin-gradle-plugin 是创建独立、可复用、可发布的 Gradle 插件项目的最直接方式,它自动生成 Kotlin DSL 结构、gradlePlugin 块、META-INF 配置及插件类,支持类型安全与 IDE 优化,并推荐通过 includeBuild 进行本地测试以暴露真实兼容性问题。

gradle init --type kotlin-gradle-plugin 是创建独立 Gradle 插件项目的最直接方式,它生成的结构开箱即用,比手写 buildSrc 更适合复用、发布和跨项目共享。
用 gradle init 初始化插件项目
gradle init 会自动配置好插件开发所需的最小依赖、目录结构和元信息。推荐使用 Kotlin(比 Groovy 更类型安全、IDE 支持更好),命令如下:
gradle init --type kotlin-gradle-plugin
执行后你会得到:
-
build.gradle.kts已声明gradlePlugin块和pluginBundle配置 -
src/main/kotlin下自动生成一个MyPlugin.kt,实现Plugin -
src/main/resources/META-INF/gradle-plugins/下有com.example.myplugin.properties,定义了插件 ID
常见错误现象:
- 执行
./gradlew build失败,报错Could not find method gradlePlugin():说明你用了旧版 Gradle(settings.gradle.kts 是否存在,以及是否在根build.gradle.kts中正确应用了plugins { id("org.gradle.kotlin.kotlin-dsl") }
插件 ID 和 properties 文件必须严格匹配
插件 ID(如 com.example.myplugin)不是随便起的。它必须和 src/main/resources/META-INF/gradle-plugins/com.example.myplugin.properties 的文件名完全一致,且该文件中必须包含:
implementation-class=com.example.myplugin.MyPlugin
否则在其他项目中 plugins { id("com.example.myplugin") } 会报错:
Plugin [id: 'com.example.myplugin'] was not found in any of the following sources:
注意点:
- 文件路径大小写敏感,
META-INF必须全大写 -
implementation-class的值必须是完整类名(含包路径),且类必须 public、无参构造 - 不要手动删掉
gradlePlugin { plugins { ... } }块——它负责把插件注册进构建产物的plugin.jar的 MANIFEST
本地测试插件:用 includeBuild 而非 buildSrc
独立插件项目建好后,想在另一个项目里试用,别复制代码,用组合构建(composing build):
在目标项目的 settings.gradle.kts 里加:
pluginManagement {
includeBuild("../myplugin")
}
然后在 build.gradle.kts 中就能直接:
plugins {
id("com.example.myplugin")
}
关键原因:
-
includeBuild让 Gradle 把插件项目当作“已发布的二进制插件”来解析,能提前暴露 classpath 冲突、API 版本不兼容等问题 - 而
buildSrc是源码级内联,容易掩盖插件实际发布后的行为差异(比如你在buildSrc里用了project.extensions.findByType,但发布后别人用时可能因 Gradle 版本升级而失效)
发布前务必检查 gradlePlugin 块中的版本约束
Gradle 插件的兼容性高度依赖 gradlePlugin { plugins { ... } } 里的 tags 和 website 等字段,但最容易被忽略的是 sinceVersion 和 testedWithGradleVersion:
gradlePlugin {
plugins {
register("myPlugin") {
id = "com.example.myplugin"
implementationClass = "com.example.myplugin.MyPlugin"
displayName = "My Custom Plugin"
description = "Does something useful"
tags.set(listOf("custom", "build"))
// 这行决定插件能否被特定 Gradle 版本加载
sinceVersion = "8.4" // 插件代码用了 8.4+ 的 API,就填这个
}
}
}
如果你的插件用了 Provider.flatMap 或 Project.layout.projectDirectory 等较新 API,却没设 sinceVersion,下游项目用低版本 Gradle 加载时不会报编译错,而是在运行时抛 NoSuchMethodError —— 这类问题极难定位。
真正麻烦的点不在怎么写,而在“写完之后,别人用的时候会不会因为 Gradle 版本、Kotlin 版本、或者 classloader 隔离策略而静默失败”。所以本地验证一定要覆盖至少两个主流 Gradle 小版本(如 8.5 和 8.9),并用 TestKit 写集成测试,而不是只跑 ./gradlew build。











