应用插件的不同方法? (Gradle Kotlin DSL)

时间:2018-01-16 21:50:35

标签: gradle kotlin gradle-kotlin-dsl

尝试将这个项目的构建迁移到GSK。 我们在Groovy中有这个:

allprojects {
    apply plugin: 'java'
...
    sourceSets {
        ...
    }
    sourceCompatibility = ...
}

因此,在确定如何访问Kotlin中的插件约定时,我发现:

allprojects {
    plugins {
        java apply true
    }
    ...
    println("Project $name, plugins: ${plugins}") // empty list
    val java = the<JavaPluginConvention>() // throws exception
}

但如果你这样做:

allprojects {
    apply {
        plugin(JavaPlugin::class.java)
    }
}

插件已应用,约定可以访问

WTH?

1 个答案:

答案 0 :(得分:3)

此问题并非Kotlin所特有,并且是由于比赛条件所致。在评估脚本时,它可能尚未将插件添加到类路径中。这是创建plugins块的众多原因之一,因为在buildscript阶段,它是在其余脚本评估之前专门评估的。就是说,只有在此块位于脚本顶部时才执行此特殊处理,而不是在subprojectsallprojects块中时才进行特殊处理,因为这些块在技术上是任意的,以后会进行评估确保buildscript是幂等的。就您而言,您只是将比赛放在allprojects块中来进行比赛,因此很幸运。

在处理多项目构建时,这是有问题的,但是,如果可能的话,最好是使用plugins约束语法在apply false块中声明插件,以将其添加到构建的类路径中在buildscript阶段。然后,您就可以稍后在脚本评估期间通过插件的ID应用插件(不需要版本,因为它仅用于获取依赖项)。

一个例子:

plugins {
    id("org.gradle.sample.hello") version "1.0.0" apply false
}

subprojects {
    apply(plugin = "org.gradle.sample.hello")
}

Gradle User Guide在解释如何使用它们以及在多模块项目中需要考虑的平衡方面做得很好。

由于某些插件的编写方式的性质,在某些情况下可能还会出现其他问题,但是如果插件作者遵循最佳实践准则,就可以了。