Gradle给您带来了Kotlin依赖项的错误版本

Gradle给您带来了Kotlin依赖项的错误版本,kotlin,gradle,gradle-plugin,gradle-kotlin-dsl,Kotlin,Gradle,Gradle Plugin,Gradle Kotlin Dsl,这里有几个关于Stackoverflow的问题,关于Kotlin编译器警告,当不同版本的Kotlin JAR在类路径中混合时 这是一个不同的问题,涉及到使用Kotlin开发Gradle插件时的情况。当您至少有以下情况之一时: kotlin dsl插件应用 javagradle插件plugin被应用 添加了gradleApi()依赖项 添加了gradleKotlinDsl()依赖项 还有Kotlin插件,比如Kotlin(“jvm”)版本“1.4.10”,例如: plugins { j

这里有几个关于Stackoverflow的问题,关于Kotlin编译器警告,当不同版本的Kotlin JAR在类路径中混合时

这是一个不同的问题,涉及到使用Kotlin开发Gradle插件时的情况。当您至少有以下情况之一时:

  • kotlin dsl
    插件应用
  • javagradle插件
    plugin被应用
  • 添加了
    gradleApi()
    依赖项
  • 添加了
    gradleKotlinDsl()
    依赖项
还有Kotlin插件,比如
Kotlin(“jvm”)版本“1.4.10”
,例如:

plugins {
    java
    kotlin("jvm") version "1.4.10"
    `kotlin-dsl`
    `java-gradle-plugin`
}
你会出名的:

w: Runtime JAR files in the classpath should have the same version. These files were found in the classpath:

bla-bla-bla/gradle-6.7/lib/kotlin-stdlib-1.3.72.jar (version 1.3)
bla-bla-bla/modules-2/files-2.1/.../kotlin-stdlib-jdk8-1.4.10.jar (version 1.4)
and so on for every Kotlin jar

w: Consider providing an explicit dependency on kotlin-reflect 1.4 to prevent strange errors
w: Some runtime JAR files in the classpath have an incompatible version. Consider removing them from the classpath
这里,Kotlin 1.3.72是Gradle 6.7的嵌入式版本,Kotlin 1.4.10是您手动添加的版本。
问题在于
gradleApi()
gradleKotlinDsl()
,因为它们直接将Kotlin jar添加为本地文件系统文件,从而绕过了Gradle依赖项版本解析。

我发现解决此问题的唯一方法是在解决不正确的配置之前删除不正确的依赖项。这是我build.gradle.kts的一部分:

import org.gradle.api.internal.artifacts.dependencies.DefaultSelfResolvingDependency
import org.gradle.api.internal.artifacts.dsl.dependencies.DependencyFactory.ClassPathNotation
import org.gradle.internal.component.local.model.OpaqueComponentIdentifier

plugins {
    java
    kotlin("jvm") version "1.4.10"
    `kotlin-dsl`
    `java-gradle-plugin`
}

project.afterEvaluate {
    // Stupid `kotlin-dsl` and `java-gradle-plugin` plugins adds gradle embedded Kotlin dependencies
    //  directly as files providing you with incorrect classpath with mixed versions of Kotlin jars.
    // This code removes such dependencies.

    // First create a copy of embedded Kotlin dependencies - we only need to remove Kotlin jars from them.
    configurations.create("gradlefix").also { cfg ->
        dependencies {
            add(cfg.name, gradleApi())
            add(cfg.name, gradleKotlinDsl())
        }
    }

    // Here are all non-Kotlin jars from gradleKotlinDsl and gradleApi.
    val neededEmbeddedDependencies = configurations["gradlefix"].files
        .filterIsInstance<File>()
        .filterNot {
            it.name.startsWith("kotlin-")
                    && it.name.endsWith(".jar")
        }

    // Now remove embedded Kotlin from all configuration, but keep needed embedded jars.
    // It is expected that configurations are not yet resolved.
    configurations
        .filterNot { it.name == "gradlefix" }
        .forEach { cfg ->
            cfg.resolutionStrategy.eachDependency {
                // Needed if you use chain of `includeBuild`s
                if (requested.group == "org.jetbrains.kotlin") {
                    useVersion("1.4.10")
                }
            }

            val removed = cfg.dependencies.removeIf {
                val notation = ((it as? DefaultSelfResolvingDependency)
                    ?.targetComponentId as? OpaqueComponentIdentifier)
                    ?.classPathNotation

                notation == ClassPathNotation.GRADLE_API
                        || notation == ClassPathNotation.GRADLE_KOTLIN_DSL
            }

            if (removed) {
                dependencies {
                    add(cfg.name, project.files(*neededEmbeddedDependencies.toTypedArray()))
                }
            }
        }
}

dependencies {
    implementation(platform("org.jetbrains.kotlin:kotlin-bom"))
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
    implementation("org.jetbrains.kotlin:kotlin-gradle-plugin")
    implementation("org.jetbrains.kotlin:kotlin-reflect")
    // implementation(gradleApi()) // already added by java-gradle-plugin plugin
    // implementation(gradleKotlinDsl()) // already added by kotlin-dsl plugin
}
import org.gradle.api.internal.artifacts.dependencies.DefaultSelfResolvingDependency
导入org.gradle.api.internal.artifacts.dsl.dependency.DependencyFactory.ClassPathNotation
导入org.gradle.internal.component.local.model.OpaqueComponentIdentifier
插件{
JAVA
kotlin(“jvm”)版本“1.4.10”
`科特林dsl`
`java gradle插件`
}
项目后评估{
//愚蠢的'kotlin dsl'和'java gradle plugin'插件添加了gradle嵌入的kotlin依赖项
//直接作为文件使用Kotlin JAR的混合版本提供不正确的类路径。
//此代码将删除此类依赖项。
//首先创建嵌入式Kotlin依赖项的副本-我们只需要从中删除Kotlin JAR。
创建(“gradlefix”)。同时{cfg->
依赖关系{
添加(cfg.name,gradleApi())
添加(cfg.name,gradleKotlinDsl())
}
}
//这是所有来自gradleKotlinDsl和gradleApi的非Kotlin罐。
val needembeddeddependencies=配置[“gradlefix”].文件
.filterIsInstance()
filterNot先生{
it.name.startsWith(“kotlin-”)
&&it.name.endsWith(“.jar”)
}
//现在从所有配置中删除嵌入式Kotlin,但保留所需的嵌入式JAR。
//预计配置尚未解决。
配置
.filterNot{it.name==“gradlefix”}
.forEach{cfg->
cfg.resolutionStrategy.eachDependency{
//如果您使用'includebild'链,则需要
if(request.group==“org.jetbrains.kotlin”){
使用版本(“1.4.10”)
}
}
val removed=cfg.dependencies.removeIf{
val表示法=((它作为?DefaultSelfResolvingDependency)
?targetComponentId作为?不透明成分识别器)
?类路径表示法
notation==ClassPathNotation.GRADLE\u API
||notation==ClassPathNotation.GRADLE\u KOTLIN\u DSL
}
如果(已删除){
依赖关系{
添加(cfg.name,project.files(*neededEmbeddedDependencies.toTypedArray())
}
}
}
}
依赖关系{
实施(平台(“org.jetbrains.kotlin:kotlin bom”))
实现(“org.jetbrains.kotlin:kotlin-stdlib-jdk8”)
实现(“org.jetbrains.kotlin:kotlin-gradle插件”)
实施(“org.jetbrains.kotlin:kotlin reflect”)
//实现(gradleApi())//已由java gradle插件添加
//实现(gradleKotlinDsl())//已由kotlin dsl插件添加
}

什么不能简单地省略
kotlin dsl
插件?它说它带有嵌入式stdlib,所以你应该知道你在做什么。请看我的插件。@AbhijitSarkar,将你的
kotlin(“jvm”)
更改为
kotlin(“jvm”)版本“1.4.10”
,你的构建时跟踪器也会遇到同样的问题。您没有这个问题的唯一原因是因为您使用的是嵌入Gradle 6.5.1中的Kotlin 1.3.72。当然,我可以省略
kotlin dsl
,但是我们都使用的
java gradle插件呢?如果必须支持1.4,请使用。就像你使用的任何依赖一样,Gradle也有它的包袱。