5

试图将这个项目的构建迁移到 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)
    }
}

应用插件并且约定变得可访问

什么?

4

1 回答 1

8

这个问题不是 Kotlin 特有的,而是由于竞争条件造成的。在评估脚本时,它可能尚未将插件添加到类路径中。这是创建块的众多原因之一,因为它是在一个阶段plugins的其余脚本评估之前专门评估的。buildscript尽管如此,这种特殊处理仅在此块位于脚本顶部时才进行,而不是在它位于 a subprojectsorallprojects块内时,因为这些块在技术上是任意的,稍后会对其进行评估以确保它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 用户指南很好地解释了如何使用这些,以及在多模块项目中需要考虑的平衡。

由于某些插件的编写方式的性质,可能会出现其他问题,但如果插件作者遵循最佳实践指南,你会没事的。

于 2018-12-08T03:09:00.410 回答