Kotlin-dsl-samples: KT-28013 - Invoke method is not called when NamedDomainObjectContainer is a field named configure

Created on 12 Oct 2018  路  3Comments  路  Source: gradle/kotlin-dsl-samples

This example can be found here at the provided branch:
https://github.com/GradleWeaver/simple-jlink/tree/crashing-example

(The branch is called "crashing-example" because before I updated my IJ kotlin plugin, IJ was hanging requiring a restart because of this issue.)

This is the extension I have declared:

open class JLinkExtension
@Inject
internal constructor(
        project: Project
) {
    val configure: NamedDomainObjectContainer<JLinkOptions> = project.container(JLinkOptions::class.java) { name ->
        JLinkOptions(name = name)
    }
}

This is the usage of said extension (found at samples/simple-jar/build.gradle.kts in the above repo)

jlink {
    configure {
    }
}

It seems that configure is resolving to the wrong overload in Gradle.
It's not using the NamedDomainObjectContainer.invoke method but is instead calling Project.configure.

Your Environment

------------------------------------------------------------
Gradle 4.10.2
------------------------------------------------------------

Build time:   2018-09-19 18:10:15 UTC
Revision:     b4d8d5d170bb4ba516e88d7fe5647e2323d791dd

Kotlin DSL:   1.0-rc-6
Kotlin:       1.2.61
Groovy:       2.4.15
Ant:          Apache Ant(TM) version 1.9.11 compiled on March 23 2018
JVM:          10.0.1 ("Oracle Corporation" 10.0.1+10)
OS:           Mac OS X 10.14 x86_64

bug jetbrains kt-compiler

Most helpful comment

In a similar fashion, when using the application plugin with static task accessors run resolves to the Kotlin Stdlib run method

tasks {
  run {
    // TaskContainerScope, not JavaExec
  }
}

Using the same (run) trick works.

All 3 comments

The type of your configure val should be NamedDomainObjectContainer instead of NamedDomainObjectCollection.

But, you're right, the kotlin compiler resolves configure {} to the closest available function which is Project.configure {} missing the invoke operator present on your val configure. This looks like a bug.

A workaround is to put parentheses around configure to explicitely resolve the val first:

jlink {
    (configure) {

    }
}

In a similar fashion, when using the application plugin with static task accessors run resolves to the Kotlin Stdlib run method

tasks {
  run {
    // TaskContainerScope, not JavaExec
  }
}

Using the same (run) trick works.

Was this page helpful?
0 / 5 - 0 ratings