Search code examples
gradlegradle-plugingradle-kotlin-dslprecompiled

Gradle pre-compiled script plugin fails with `expression ... cannot be invoked as a function` for first block


I have the following pre-compiled script plugin, which applies a Gradle core plugin and an external plugin (via id(...)):

// buildSrc/main/kotlin/my-template.gradle.kts:
import org.gradle.api.JavaVersion

plugins {
    java
    id("com.diffplug.gradle.spotless") // commenting this line "fixes" the problem, WHY?
}

java {
    sourceCompatibility = JavaVersion.VERSION_11
}

with this build.gradle.kts in buildSrc:

// buildSrc/build.gradle.kts:
repositories {
    maven("https://nexus.ergon.ch/repository/secure-public/")
}

plugins {
    `kotlin-dsl`
    id("com.diffplug.gradle.spotless") version "3.25.0"
}

The build fails with the following message: Expression 'java' cannot be invoked as a function. The function 'invoke()' is not found

$ ./gradlew tasks

> Task :buildSrc:compileKotlin FAILED
The `kotlin-dsl` plugin applied to project ':buildSrc' enables experimental Kotlin compiler features. For more information see https://docs.gradle.org/5.6.4/userguide/kotlin_dsl.html#sec:kotlin-dsl_plugin
e: .../buildSrc/src/main/kotlin/my-template.gradle.kts: (8, 1): Expression 'java' cannot be invoked as a function. The function 'invoke()' is not found
e: .../buildSrc/src/main/kotlin/my-template.gradle.kts: (8, 1): Unresolved reference. None of the following candidates is applicable because of receiver type mismatch: 
internal val OrgGradlePluginGroup.java: PluginDependencySpec defined in gradle.kotlin.dsl.plugins._279e7abc24718821845464f1e006d45a in file PluginSpecBuilders.kt
public val <T> KClass<TypeVariable(T)>.java: Class<TypeVariable(T)> defined in kotlin.jvm
public val PluginDependenciesSpec.java: PluginDependencySpec defined in org.gradle.kotlin.dsl
e: .../buildSrc/src/main/kotlin/my-template.gradle.kts: (9, 5): Unresolved reference: sourceCompatibility


FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':buildSrc:compileKotlin'.
> Compilation error. See log for more details

I am using Gradle 5.6.4 and pre-compiled script plugins should be able to leverage type-safe accessors since Gradle 5.3.

(Also, the java {} block is highlighted in red in IntelliJ and there is no code completion)

This problem occurs as soon as there is any external plugin listed in the plugins {} block, it is not related to the specific spotless plugin.

The problem seems to always affect the first block after the plugins {} block, so it doesn't seem to be related to the specific java plugin either.

What do I need to change to make my plugin work?


Solution

  • The problem is that in buildSrc/build.gradle.kts the external Gradle plugin id("com.diffplug.gradle.spotless") is applied (via the plugins {} block), but there is no dependency declared (via the dependencies block) on the artifact providing the plugin:

    plugins {
        `kotlin-dsl`
        // use "apply false" to specify the exact version (which is
        // forbidden in the pre-compiled script plugin itself) without applying the plugin
        id("com.diffplug.gradle.spotless") version "3.25.0" apply false 
    }
    
    dependencies {
        // actually depend on the plugin to make it available:
        implementation(plugin("com.diffplug.gradle.spotless", version = "3.25.0")) 
    }
    
    // just a helper to get a syntax similar to the plugins {} block:
    fun plugin(id: String, version: String) = "$id:$id.gradle.plugin:$version"