当前位置: 首页 > 知识库问答 >
问题:

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

施令雪
2023-03-14

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

这个问题是一个不同的问题,涉及到使用静态编程语言开发Gradle插件时的情况。当您至少有以下一项:

  • kotlin dsl插件应用
  • javagradle插件plugin被应用
  • 添加了gradleApi()依赖项
  • 添加了gradleKotlinDsl()依赖项

你有静态编程语言插件,如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

静态编程语言1.3.72是Gradle 6.7的嵌入式版本,静态编程语言1.4.10是您手动添加的版本。问题出在gradleApi()gradleKotlinDsl()上,因为它们直接将静态编程语言罐添加为本地文件系统文件,从而绕过Gradle依赖版本解析。

共有2个答案

江洲
2023-03-14

我得出了一个相似的解决方案,但仍然非常不同:

我发现我可以撤消添加默认命名的Gradle依赖项(GradleAppi()gradleKotlinDsl()gradleTestKit()),并提供了我自己的版本,其中不包含嵌入的Kotlin依赖项。

你可以在这里的真实环境中找到它

fun Project.replaceGradlePluginAutoDependenciesWithoutKotlin() {
    plugins.withId("org.gradle.java-gradle-plugin") {
        @Suppress("DEPRECATION")
        dependencies {
            // Undo org.gradle.plugin.devel.plugins.JavaGradlePluginPlugin.applyDependencies
            if (configurations[JavaPlugin.COMPILE_CONFIGURATION_NAME].dependencies.remove(gradleApi())) {
                add(JavaPlugin.COMPILE_CONFIGURATION_NAME, gradleApiWithoutKotlin())
            }

            // Undo org.gradle.plugin.devel.plugins.JavaGradlePluginPlugin.TestKitAndPluginClasspathDependenciesAction
            afterEvaluate {
                gradlePlugin.testSourceSets.forEach {
                    if (configurations[it.compileConfigurationName].dependencies.remove(gradleTestKit())) {
                        add(it.compileConfigurationName, gradleTestKitWithoutKotlin())
                    }
                }
            }
        }
    }

    plugins.withId("org.gradle.kotlin.kotlin-dsl.base") { // applied from org.gradle.kotlin.kotlin-dsl
        dependencies {
            // based on org.gradle.kotlin.dsl.plugins.embedded.kotlinArtifactConfigurationNames (in EmbeddedKotlinPlugin.kt)
            val kotlinArtifactConfigurationNames = listOf(
                JavaPlugin.COMPILE_ONLY_CONFIGURATION_NAME,
                JavaPlugin.TEST_IMPLEMENTATION_CONFIGURATION_NAME
            )
            kotlinArtifactConfigurationNames.forEach {
                // Undo org.gradle.kotlin.dsl.plugins.base.KotlinDslBasePlugin.addGradleKotlinDslDependencyTo
                if (configurations[it].dependencies.remove(gradleKotlinDsl())) {
                    add(it, gradleKotlinDslWithoutKotlin())
                }
            }
        }
    }
}

fun DependencyHandler.gradleApiWithoutKotlin(): Dependency =
    withoutKotlin(ClassPathNotation.GRADLE_API)

fun DependencyHandler.gradleKotlinDslWithoutKotlin(): Dependency =
    withoutKotlin(ClassPathNotation.GRADLE_KOTLIN_DSL)

fun DependencyHandler.gradleTestKitWithoutKotlin(): Dependency =
    withoutKotlin(ClassPathNotation.GRADLE_TEST_KIT)

private fun DependencyHandler.withoutKotlin(notation: ClassPathNotation): Dependency {
    // Originally created in org.gradle.api.internal.notations.DependencyClassPathNotationConverter.create
    val gradleApi = create(notation) as FileCollectionDependency
    val filteredSource = gradleApi.files.filter { !it.name.startsWith("kotlin-") }
    val displayName = OpaqueComponentIdentifier("${notation.displayName} (without Kotlin)")
    return DefaultSelfResolvingDependency(displayName, filteredSource as FileCollectionInternal)
}
翟宾实
2023-03-14

我发现解决此问题的唯一方法是在解决不正确的配置之前删除不正确的依赖项。这是我身体的一部分。格拉德尔。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
}
 类似资料:
  • 我正在尝试添加以下依赖项:

  • 我有一个类似于 B项目依赖于A项目 项目B的settings.gradle和build.gradle如下所示 格雷德尔酒店 格雷德尔先生 当我尝试在本地机器(Gradle版本3.2)上构建项目B时,它成功构建,一切看起来都很好。 当我尝试在jenkins中构建相同的项目(与我的本地版本相同的gradle版本)时,我得到了错误 它看起来像詹金斯,它是无法计算出相对路径。 我该怎么解决这个问题? 在j

  • 我可以在一个多模块gradle项目中复制一个模块的所有依赖项,比如 但实际上,我只需要通过应用项目组id的过滤器来复制项目依赖项 在Gradle中,使用Kotlin DSL的正确方法是什么?

  • 我已经将我的声明为我试图构建的Gradle项目的存储库: maven缓存已经包含工件,包括工件(pom和zip)。如果我在另一个Maven项目中添加了依赖关系,那么它将被正确加载: 现在,我以调试和脱机模式运行Gradle。我从MavenLocal获得了一些正确解析的工件,比如: 但是,其中一个工件似乎被放到了另一个存储库中,显然没有找到(因为它是离线的,我必须离线,因为“安全网络访问原因”[我们

  • 我有两个Spring Boot项目,并希望使用其中一个作为MAVEN依赖在其他。 项目刮板取决于数据库项目 项目数据库包含数据库层(实体和DAO在此构建和测试) 在数据库项目中,我必须重写Hibernate版本,并按照选项2中https://spring.io/blog/2016/04/13/overriding-dependency-versions-with-spring-boot描述。 这很