使用Java 9/10和Gradle的Kotlin DSL构建Gradle Kotlin项目

4
这是关于在Gradle中构建Kotlin + Java 9项目的后续内容,链接如下:Building a Kotlin + Java 9 project with Gradle。在链接的帖子中使用了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"
}

这是我的module-info.java文件:

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

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


1个回答

3

这是一种自问自答的形式(我并不完全了解这个问题,因此解释可能不正确)。我得出的结论纯粹是基于经验,并基于从Kotlin DSL转换为Gradle's 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

这个操作主要是将Kotlin编译输出中的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。


4
我仍然认为这不是最好的解决方案,所以如果有更好的答案,将不胜感激。 - TeXnician

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接