You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义Gradle Task报错:非静态内部类问题求助

解决Gradle自定义Task非静态内部类报错问题

核心问题解决

报错的直接原因是MyTask被定义为非静态内部类,Gradle无法实例化这种类型的Task。以下是具体解决方法:

1. 将MyTask改为顶级类

如果你的MyTask写在模块的build.gradle.kts中,确保它位于脚本最外层,不要嵌套在任何类、函数或闭包内部:

// 放在build.gradle.kts最顶部,作为顶级类
abstract class MyTask : DefaultTask() {
    @get:Input
    abstract val moduleName: Property<String>

    @get:Input
    abstract val moduleArtifactId: Property<String>

    @get:Input
    abstract val repositoryUrl: Property<String>

    @TaskAction
    fun execute() {
        println("hello from my task, my name is ${moduleName.get()}, ${moduleArtifactId.get()}, ${repositoryUrl.get()}")
        project.publishing {
            publications {
                create<MavenPublication>("release") {
                    groupId = project.properties["groupId"] as String
                    version = project.properties["version"] as String
                    artifactId = moduleArtifactId.get()
                    project.afterEvaluate {
                        from(components["release"])
                    }
                    artifact("$buildDir/outputs/aar/$artifactId-release.aar") {
                        classifier = "release"
                    }
                }
            }
            repositories {
                maven {
                    this.name = moduleName.get()
                    this.url = uri(repositoryUrl.get())

                    credentials {
                        username = "my-user-name"
                        password = "my-password"
                    }
                }
            }
        }
    }
}

// 注册Task
tasks.register<MyTask>("mytask") {
    moduleName.set("module's name")
    moduleArtifactId.set("artifact's id")
    repositoryUrl.set("remote repo's url")
}

如果需要在多模块复用该Task,更推荐将它放在buildSrc目录的顶级Kotlin文件中:

  • 在项目根目录创建buildSrc/src/main/kotlin/MyTask.kt
  • 将MyTask类写入该文件作为顶级类
  • 所有模块的build.gradle.kts可直接引用该类,无需重复定义

2. 若必须嵌套则改为静态嵌套类(不推荐)

如果需要嵌套在其他类中,确保它是Kotlin的静态嵌套类(即不加inner关键字的嵌套类,Kotlin默认嵌套类为静态):

object TaskContainer {
    // 静态嵌套类,Gradle可实例化
    abstract class MyTask : DefaultTask() {
        // ... 类内容同前
    }
}

// 注册时引用静态嵌套类
tasks.register<TaskContainer.MyTask>("mytask") {
    moduleName.set("module's name")
    moduleArtifactId.set("artifact's id")
    repositoryUrl.set("remote repo's url")
}

额外优化建议

你的Task逻辑存在潜在问题:在@TaskAction中配置publishing扩展,会导致发布配置仅在Task执行阶段初始化,违反Gradle配置/执行阶段分离原则。建议将发布配置移到配置阶段,Task仅负责触发发布:

abstract class MyTask : DefaultTask() {
    @get:Input
    abstract val moduleName: Property<String>

    @get:Input
    abstract val moduleArtifactId: Property<String>

    @get:Input
    abstract val repositoryUrl: Property<String>

    // 依赖发布任务,确保触发发布动作
    init {
        val repoNameCapitalized = moduleName.get().replaceFirstChar { it.uppercase() }
        dependsOn("publishReleasePublicationTo${repoNameCapitalized}Repository")
    }

    @TaskAction
    fun execute() {
        println("开始发布模块: ${moduleName.get()},制品ID: ${moduleArtifactId.get()}")
    }
}

// 提取发布配置到单独函数,在配置阶段执行
fun Project.setupPublishing(artifactId: String, repoUrl: String, repoName: String) {
    publishing {
        publications {
            create<MavenPublication>("release") {
                groupId = project.properties["groupId"] as String
                version = project.properties["version"] as String
                this.artifactId = artifactId
                from(components["release"])
                artifact("$buildDir/outputs/aar/$artifactId-release.aar") {
                    classifier = "release"
                }
            }
        }
        repositories {
            maven {
                name = repoName
                url = uri(repoUrl)
                credentials {
                    username = "my-user-name"
                    password = "my-password"
                }
            }
        }
    }
}

// 注册Task时同时完成发布配置
tasks.register<MyTask>("mytask") {
    val repoName = "module's name"
    val artifactId = "artifact's id"
    val repoUrl = "remote repo's url"

    moduleName.set(repoName)
    moduleArtifactId.set(artifactId)
    repositoryUrl.set(repoUrl)

    // 配置阶段初始化发布设置
    project.setupPublishing(artifactId, repoUrl, repoName)
}

内容的提问来源于stack exchange,提问作者brzi_gonzales

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 01:57:28