Создание проекта Kotlin + Java 9 с помощью Gradle
Я новичок в Gradle (и, честно говоря, Java 9), и я пытаюсь использовать Gradle для создания простого проекта библиотеки, представляющего собой сочетание Java 9 и Kotlin. Более подробно, есть интерфейс в Java и реализация в Котлине; Я бы сделал все в Котлине, но modules-info.java
- это Java, так что я решил сделать так.
Я основываюсь на IntelliJ Idea, с плагином 1.2.0 kotlin и Gradle 4.3.1, определенным извне.
Схема файловой системы:
+ src
+ main
+ java
+ some.package
- Roundabout.java [an interface]
- module-info.java
+ kotlin
+ some.package.impl
- RoundaboutImpl.kt [implementing the interface]
module-info.java
:
module some.package {
requires kotlin.stdlib;
exports some.package;
}
и build.gradle
:
buildscript {
ext.kotlin_version = '1.2.0'
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
group 'some.package'
version '1.0-PRE_ALPHA'
apply plugin: 'java-library'
apply plugin: 'kotlin'
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
}
sourceCompatibility = 9
compileJava {
dependsOn(':compileKotlin')
doFirst {
options.compilerArgs = [
'--module-path', classpath.asPath,
]
classpath = files()
}
}
repositories {
mavenCentral()
}
dependencies {
compile group: 'org.jetbrains.kotlin', name: 'kotlin-stdlib', version: "$kotlin_version"
testCompile group: 'junit', name: 'junit', version: '4.12'
}
compileKotlin {
kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
kotlinOptions.jvmTarget = "1.8"
}
Обратите внимание, что мне пришлось указать путь к модулю в java-компиляционной задаче или сбой компиляции:
Ошибка: модуль не найден: kotlin.stdlib требует kotlin.stdlib;
В любом случае, теперь эта сборка завершилась с ошибкой, и я не могу понять, как ее решить:
Ошибка: пакет some.package.impl не существует
import some.package.impl.RoundaboutImpl;
ошибка: не удается найти символ
вернуть новый RoundaboutImpl < > (queueSize, parallelism, worker, threadPool);
Я думаю, что часть Kotlin компиляции идет нормально, тогда java-часть терпит неудачу, потому что она не "видит" сторону kotlin, так сказать.
Я думаю, что мне нужно как-то сказать загрузить уже скомпилированные классы kotlin в classpath; но (сначала), как это сделать в gradle? и (второй), это даже возможно? Я думаю, вы не можете смешивать путь к модулю и путь класса в Java 9.
Как я могу это решить? Я думаю, что это довольно распространенная ситуация, так как каждый модуль java9-стиля будет модулем на смешанном языке (из-за module-info.java
), поэтому я думаю, что мне не хватает чего-то действительно основного.
Спасибо заранее!
Ответы
Ответ 1
Решено! Достаточно было установить каталог компиляции kotlin в тот же каталог, что и Java:
compileKotlin.destinationDir = compileJava.destinationDir
Теперь он работает как с источниками в одном и том же дереве, так и на разных деревьях; но с quirk: задача jar
создает банку со всеми дублируемыми элементами. Я поработаю над этим, затем.
Спасибо всем!
Ответ 2
Я использую следующий скрипт gradle, где я помещаю module-info.java в src/module. Он автоматически включается в банку (без дубликатов):
if (JavaVersion.current() >= JavaVersion.VERSION_1_9) {
subprojects {
def srcModule = "src/module"
def moduleInfo = file("${project.projectDir}/$srcModule/module-info.java")
if (moduleInfo.exists()) {
sourceSets {
module {
java {
srcDirs = [srcModule]
compileClasspath = main.compileClasspath
sourceCompatibility = '9'
targetCompatibility = '9'
}
}
main {
kotlin { srcDirs += [srcModule] }
}
}
compileModuleJava.configure {
dependsOn compileKotlin
destinationDir = compileKotlin.destinationDir
doFirst {
options.compilerArgs = ['--module-path', classpath.asPath,]
classpath = files()
}
}
jar.dependsOn compileModuleJava
}
}
}
Я больше не буду обновлять его, взгляните на https://github.com/robstoll/atrium/blob/master/build.gradle
чтобы увидеть текущую версию в использовании.
Ответ 3
Принятый ответ не работает для меня (по крайней мере, не так, как он был представлен), но это то, что сработало:
plugins {
id "org.jetbrains.kotlin.jvm" version "1.3.50"
}
compileKotlin {
doFirst {
destinationDir = compileJava.destinationDir
}
}
jar {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
В соответствии с принятым ответом я получил эту ошибку:
Каталог '/path/to/project/build/classes/kotlin/main', указанный для свойство compileKotlinOutputClasses не существует.
Версия Gradle: 5,6