【问题标题】:Getting rid of warning in a Spring Boot project being migrated to the Gradle Kotlin DSL在迁移到 Gradle Kotlin DSL 的 Spring Boot 项目中消除警告
【发布时间】:2024-04-21 02:25:01
【问题描述】:

我正在将某个 Gradle 项目从 Groovy 迁移到 Kotlin DSL。

我正在使用kotlin-dsl插件并配置Spring Boot如下:

plugins {
    java
    id("org.springframework.boot").version(Versions.springBootVersion)
    `kotlin-dsl`
}

kotlin-dsl 插件的文档要求指定任何特定的 Kotlin 版本,如下所示:

避免为 kotlin-dsl 插件指定版本:

每个 Gradle 版本都旨在与特定版本的 kotlin-dsl 插件和任意 Gradle 版本之间的兼容性 并且不保证 kotlin-dsl 插件版本。使用意想不到的 构建中的 kotlin-dsl 插件版本将发出警告并 可能会导致难以诊断的问题。

这是我的应用程序类:

@SpringBootApplication
class App {
    fun main(args: Array<String>) {
        runApplication<App>(*args)
    }
}

在以class App 开头的行下,我在 IntelliJ 中看到一条警告,告诉我:

Classes annotated with '@Configuration' could be implicitly subclassed and must not be final 

我知道这是因为App 类应该声明为open。 据我所知,Kotlin 的 Gradle Spring Boot 插件应该负责在幕后为我创建一个 @SpringBootApplication 注释类 open。所以我尝试添加以下插件:

kotlin("plugin.spring") version "1.3.72"

(其中version "1.3.72" 对应 Kotlin 版本)

正如预期的那样,异常消失了。 但是,这种方法违反了在 Gradle 配置中不对 Kotlin 版本进行硬编码的推荐准则。

使用 Kotlin DSL 配置 Spring Boot 的最佳实践是什么,这样我就不必在构建脚本中硬编码 Kotlin 版本? 也许有一种方法可以消除 IntelliJ 中的警告,而无需添加 kotlin("plugin.spring") version "1.3.72" 插件? 我认为这可能是 IntelliJ 特有的问题,因为即使 kotlin("plugin.spring") 不存在,在终端使用 gradle 构建或执行项目时,我也没有看到任何类似的警告。

【问题讨论】:

    标签: spring spring-boot gradle intellij-idea gradle-kotlin-dsl


    【解决方案1】:

    Kotlin DSL Plugin 的 Gradle 用户指南是这样描述的:

    Kotlin DSL 插件提供了一种方便的方式来开发基于 Kotlin 的项目,这些项目有助于构建逻辑。这包括 buildSrc 项目、包含的构建和 Gradle 插件。

    您的 Spring Boot 应用程序不提供构建逻辑,您可能不应该为此使用插件。如果你在 Kotlin 中开发 Gradle 插件,那么它会更有意义。在这种情况下,您应该使用与您正在构建的版本相同的 Kotlin DSL Gradle API 版本,因为定位另一个版本可能有点棘手。

    我会删除插件,而是明确说明您的配置。你需要在你的构建文件中多放几行,但是这样复杂的类路径就不会被你不需要的 DSL 东西污染。

    这也意味着您需要对 Kotlin 版本进行硬编码,但这是一件好事,否则您将依赖于您正在构建的 Gradle 版本中包含的任何内容。

    例如:

    plugins {
        id("org.springframework.boot") version "2.3.0.RELEASE"
        kotlin("jvm") version "1.3.72"
        kotlin("plugin.spring") version "1.3.72"
    }
    
    dependencies {
        implementation(platform("org.springframework.boot:spring-boot-dependencies:2.3.0.RELEASE"))
        implementation(platform("org.jetbrains.kotlin:kotlin-bom"))
        implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
        implementation("org.springframework.boot:spring-boot-starter")
    }
    

    【讨论】: