I'm learning custom gradle plugins and I'm struggl...
# gradle
t
I'm learning custom gradle plugins and I'm struggling with plugin extensions. I'm currently working through the gradle guide on making the plugin configurable but i'm getting the following error when running
./gradlew tasks
locally:
Copy code
* What went wrong:
Failed to apply plugin class 'Build_gradle$FooPlugin'.
> Could not create plugin of type 'FooPlugin'.
   > The constructor for type Build_gradle.FooPlugin should be annotated with @Inject.
Heres the contents of build.gradle.kts:
Copy code
abstract class FooExtension {
    abstract val bar: Property<String>

    init {
        println("Hi from FooExt")
    }
}

class FooPlugin : Plugin<Project> {
    override fun apply(target: Project) {
        val extension = target.extensions.create<FooExtension>("foo")

        project.task("hello") {
            doLast {
                println(extension.bar.get())
            }
        }
    }
}

apply<FooPlugin>()

extensions.getByType<FooExtension>().bar.set("foo")
v
I think your problem is, that you have all that in a
.gradle.kts
file. Because of that the class
FooPlugin
is an inner class of the class
Build_gradle
and thus has the instance of the enclosing class as argument to the constructor. And as now the constructor has a parameter it would need to get the value injected which of course would not work even if the annotation were present.
t
Okay ... I think i'm following. The root issue is that
bar
isn't initalised .. so i could add something to the contstructor to initialise it
init { bar.set("baz") }
which should address the issue
When the external scope is say a standalone plugin, does the initialisation of the abstract properties occur automatically?
v
No, you totally misunderstood
🤦‍♂️ 1
bar
IS initialized, it gets implemented and initilaized by Gradle
You are looking at the wrong class
Just copy your
FooPlugin
into its own file in an included build or
buildSrc
and it should work as it is then no longer an inner class that needs the instance of the outer class in the constructor
It is very uncommon to have a plugin class within a build script, because then you could also just do the action
t
okay cool will try that
It is very uncommon to have a plugin class within a build script, because then you could also just do the action
Agreed .. but its from the official gradle docs 🤷
Okay thanks thats now working as expected
v
Ah, your problem is a different one
You changed the parameter name from the example where it is
project
to
target
, but you still do
project.task
. So
project
is the instance of the enclosing script and that's why there is a connection that cannot be initialized
If you take your initial example here and change
project.task
to
target.task
, it works.
t
ahhh that makes sense
v
Besides that it is not using task configuration avoidance