3

这是对使用 Gradle 构建 Kotlin + Java 9 项目的一种跟进。在链接的帖子中使用了带有 Groovy 的 Gradle。在我的例子中,使用了 Kotlin DSL。

基本上我有一个具有以下结构的gradle项目(这里只有相关内容):

src/
|   main/
|   |   kotlin/
|   |   |   com/example/testproject/
|   |   |   |   Main.kt
|   |   |   module-info.java
build.gradle.kts
settings.gradle

通常我会在上面运行 gradle run ,但这会导致以下错误:

module-info.java:3: error: module not found: kotlin.stdlib
  requires kotlin.stdlib;

现在这就是我的构建文件当前的样子

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

buildscript {
  var kotlin_version: String by extra
  kotlin_version = "1.2.41"

  repositories {
    mavenCentral()
  }
  dependencies {
    classpath(kotlin("gradle-plugin", kotlin_version))
  }
}

repositories {
  mavenCentral()
}

plugins {
  kotlin("jvm") version "1.2.41"
  application
}

val kotlin_version: String by extra

dependencies {
  implementation(kotlin("stdlib", kotlin_version))
  implementation(kotlin("stdlib-jdk8", kotlin_version))
  implementation(kotlin("runtime", kotlin_version))
  implementation(kotlin("reflect", kotlin_version))
}

val group = "com.example"
application {
  mainClassName = "$group.testproject.Main"
}

java {
  sourceCompatibility = JavaVersion.VERSION_1_10
  targetCompatibility = sourceCompatibility
  sourceSets {
    "main" {
      java.srcDirs("src/main/kotlin")
    }
  }
}

tasks.withType<KotlinCompile> {
  kotlinOptions.jvmTarget = "1.8"
}

这是我的模块信息.java:

module com.example.testproject {
  // Kotlin compatibility
  requires kotlin.stdlib;
  exports com.example.testproject;
}

问题:如何运行链接帖子中提供的解决方案(或任何其他解决方案),以便可以使用 Java 9/10 环境编译带有 Gradle 的 Kotlin DSL 的 Kotlin 项目?

4

1 回答 1

2

这是一种自我回答(我不完全理解这件事,所以解释可能不正确)。我在这里得出的结论纯粹是经验性的,并且基于从 Kotlin DSL 到 Gradle 的 Groovy 的转换。

我遇到的第一个问题是我有两个相互冲突的 Kotlin 函数提供程序:

  implementation(kotlin("stdlib", kotlin_version))
  implementation(kotlin("runtime", kotlin_version))

我决定使用stdlib. 所有其他依赖项不相互冲突。

更严重的问题是不同的:compileJava任务没有找到正确的类(来自项目)和模块(来自分发)。因此,我需要调整路径,如下例所示:

val compileKotlin: KotlinCompile by tasks
val compileJava: JavaCompile by tasks
compileJava.destinationDir = compileKotlin.destinationDir

这基本上编译了 Kotlins 编译输出中的 Java 类,并使 Java 从项目中找到这些类。

最后一个问题最终可以通过以下非惯用的 Kotlin 脚本来解决:

tasks {
  "compileJava" {
    dependsOn(":compileKotlin")
    if (JavaVersion.current() >= JavaVersion.VERSION_1_9) {
      inputs.property("moduleName", ext["moduleName"])
      doFirst {
        compileJava.options.compilerArgs = listOf(
            // include Gradle dependencies as modules
            "--module-path", java.sourceSets["main"].compileClasspath.asPath,
        )
        java.sourceSets["main"].compileClasspath = files()
      }
    }
  }
}

这基本上让compileJava任务使用一个空的类路径,并将模块路径设置为编译器选项到主源集(Kotlin 源集,也作为 Java 源集添加)的当前设置的 compileClasspath。

于 2018-05-21T14:20:57.663 回答