Gradle多项目中Kotlin DSL自定义脚本插件报错求助
Let's break down your problem and walk through the solutions step by step.
Why Your Original Kotlin Script Failed
The error occurs because scripts in buildSrc/src/main/gradle don't run with the same context as regular project build scripts.
When you use apply(from = "...") to import a Kotlin script from this directory, Gradle doesn't automatically inject the Gradle Kotlin DSL extensions (like the eclipse configuration block) that you'd get in a standard build.gradle.kts file. Kotlin's static typing means it can't resolve the eclipse function or its nested project block without explicit setup—unlike Groovy DSL, which relies on dynamic resolution to find these constructs.
Can You Use Kotlin DSL for Custom Script Plugins?
Absolutely! You just need to use one of two supported approaches for Kotlin DSL plugins in Gradle:
Option 1: Build a Compiled Binary Plugin (Recommended for buildSrc)
Compiled plugins in buildSrc are the most robust way to share conventions across subprojects. Here's how to set it up:
Create the plugin class in
buildSrc/src/main/kotlin/com/example/EclipseConventionPlugin.kt:import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.plugins.ide.eclipse.EclipsePlugin import org.gradle.plugins.ide.eclipse.model.Eclipse class EclipseConventionPlugin : Plugin<Project> { override fun apply(project: Project) { // Apply the Eclipse plugin first project.pluginManager.apply(EclipsePlugin::class.java) // Configure the Eclipse extension project.extensions.configure(Eclipse::class.java) { eclipse -> eclipse.project { println("Running inside eclipse closure for ${project.name}") } } } }Register the plugin by creating a properties file at
buildSrc/src/main/resources/META-INF/gradle-plugins/com.example.eclipse-convention.properties:implementation-class=com.example.EclipseConventionPluginApply the plugin to subprojects in your root
build.gradle.kts:configure(subprojects) { apply(plugin = "com.example.eclipse-convention") }
This approach ensures type safety, proper dependency resolution, and works seamlessly across all your subprojects.
Option 2: Use a Kotlin DSL Script Plugin (Non-Compiled)
If you prefer a script-based approach (similar to your Groovy setup), move the script to a location where Gradle can resolve the Kotlin DSL context correctly:
Create the script plugin in your project root at
gradle/conventions/eclipse.gradle.kts:plugins { id("eclipse") } eclipse { project { println("Running inside eclipse closure for ${project.name}") } }Apply the script to subprojects in your root
build.gradle.kts:configure(subprojects) { apply(from = rootProject.file("gradle/conventions/eclipse.gradle.kts")) }
Why this works: Scripts in the project's gradle directory are treated as project build scripts, so Gradle injects the necessary Kotlin DSL extensions automatically.
Why Placing the Script in buildSrc/src/main/kotlin Didn't Work
The buildSrc/src/main/kotlin directory is reserved for compiled Kotlin classes, not script plugins. Gradle tries to compile .gradle.kts files here as regular Kotlin code, which fails because script plugins use a different syntax and context.
内容的提问来源于stack exchange,提问作者Ravi Tiwari

