Создание проекта Gradle Kotlin с использованием Java 9/10 и DSL Gradle Kotlin - PullRequest
0 голосов
/ 20 мая 2018

Это своего рода продолжение до Создание проекта Kotlin + Java 9 с Gradle .В связанном посте используется Gradle с Groovy.В моем случае используется 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"
}

И это мой модуль-info.java:

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

Вопрос: Как запустить решение, указанное в связанном посте (или любом другом решении), чтобы проект Kotlin с Kotlin DSL от Gradle можно было скомпилировать с использованием среды Java 9/10?

1 Ответ

0 голосов
/ 21 мая 2018

Это своего рода ответ на свой вопрос (я не до конца понимаю этот вопрос, поэтому объяснения могут быть неверными).Выводы, которые я здесь делаю, являются чисто эмпирическими и основаны на преобразовании из Kotlin DSL в Groovy и обратно Gradle.

Первая проблема, с которой я столкнулся, заключалась в том, что у меня было два конфликтующих поставщика для функций 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

Это в основном компилирует классы Java в скомпилированном выводе Kotlins и заставляет 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 использовать пустой путь к классу и задает путь к модулю в качестве параметра компилятора для текущего установленного compileClasspathосновной исходный набор (исходный набор Kotlin, который также добавляется как исходный набор Java).

...