Search code examples
gradlekotlin

could not create an instance of gradle plugin extension


I am trying to write gradle plugin using kotlin. It supposed to work like this. While providing configuration

apply plugin: 'appenv'

app {
    srcLink ""
    downloadPath ""
}

It should allow to download file from srcLink and store in downloadPath using task downloadAll

I created extension class

open class ApplicationEnvironmentExtension {
    val project: Any?

    constructor(project: Any?) {
        this.project = project
    }

    var srcLink: String = ""
    var downloadPath: String = ""
}

Create plugin class

class ApplicationEnvironmentPlugin : Plugin<Project> {

    override fun apply(project: Project) {
        project.extensions.create("app", ApplicationEnvironmentExtension::class.java)
        project.task(mapOf ("type" to Download::class.java), "downloadAll")
    }
}

And here his the task

class Download : DefaultTask() {

    @TaskAction
    fun download() {
        val extension = this.project.extensions.getByName("app") as ApplicationEnvironmentExtension
        DownloadUtils.download(extension.srcLink, extension.downloadPath)
    }
}

I build it and add it as jar dependency to my project. To check whether tasks were added I run gradle tasks. But during that I get the error

Could not create an instance of type com.lapots.gradle.plugins.appenv.ApplicationEnvironmentExtension_Decorated.

In stacktrace I get

Caused by: org.gradle.internal.reflect.ObjectInstantiationException: Could not create an instance of type com.lapots.gradle.plugins.appenv.ApplicationEnvironmentExtension_Decorated.
        at org.gradle.internal.reflect.DirectInstantiator.newInstance(DirectInstantiator.java:53)
        at org.gradle.api.internal.ClassGeneratorBackedInstantiator.newInstance(ClassGeneratorBackedInstantiator.java:36)
        at org.gradle.api.internal.plugins.DefaultConvention.create(DefaultConvention.java:106)
        at com.lapots.gradle.plugins.appenv.ApplicationEnvironmentPlugin.apply(ApplicationEnvironmentPlugin.kt:11)
        at com.lapots.gradle.plugins.appenv.ApplicationEnvironmentPlugin.apply(ApplicationEnvironmentPlugin.kt:8)
        at org.gradle.api.internal.plugins.ImperativeOnlyPluginApplicator.applyImperative(ImperativeOnlyPluginApplicator.java:35)
        at org.gradle.api.internal.plugins.RuleBasedPluginApplicator.applyImperative(RuleBasedPluginApplicator.java:43)
        at org.gradle.api.internal.plugins.DefaultPluginManager.doApply(DefaultPluginManager.java:144)
        ... 58 more         
Caused by: java.lang.IllegalArgumentException: Could not find any public constructor for class com.lapots.gradle.plugins.appenv.ApplicationEnvironmentExtension_Decorated which accepts parameters [].
        at org.gradle.internal.reflect.DirectInstantiator.newInstance(DirectInstantiator.java:44)
        ... 65 more    

What is the problem? Should I provide some addtional constructors to extension?


Solution

  • Extensions need a default (no-arg) constructor. If you really need to assign a field to a value in your extension, you can use lateinit var and assign it after creating the extension in your plugin.

    In this case, it doesn't look like you need your project field anyway, so you can get rid of that and the constructor. Otherwise if you do need the field, still remove the constructor, but you'll need to make project a var with a default value of null.