【发布时间】:2017-12-05 15:59:06
【问题描述】:
我对 Gradle(老实说,还有 Java 9)还很陌生,我正在尝试使用 Gradle 构建一个简单的库项目,它混合了 Java 9 和 Kotlin。更详细地说,Java 中有一个接口,Kotlin 中有一个实现;我会在 Kotlin 中做所有事情,但 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 compile 任务上指定模块路径,否则编译失败:
错误:找不到模块:kotlin.stdlib 需要 kotlin.stdlib;
无论如何,现在这个构建失败并出现这个错误,我不知道如何解决它:
错误:包 some.package.impl 不存在
导入 some.package.impl.RoundaboutImpl;
错误:找不到符号
return new RoundaboutImpl(queueSize, parallelism, worker, threadPool);
我认为编译的 Kotlin 部分运行正常,然后 java 部分失败,因为它没有“看到”kotlin 方面,可以这么说。
我想我应该告诉它在类路径中加载已经编译的 kotlin 类;但是(首先)我如何在 gradle 中做到这一点?和(第二个)有可能吗?我认为你不能在 Java 9 中混合模块路径和类路径。
我该如何解决这个问题?我认为这是一种很常见的情况,因为每个 java9 样式的模块都是混合语言模块(因为 module-info.java),所以我认为我在这里遗漏了一些非常基本的东西。
提前致谢!
【问题讨论】:
-
学究起来,
module-info.java不是真的 Java,它是一种特殊的 DSL,但是 Kotlin 开发人员说他们 see no value in reinventing it 所以它会保持原样。 -
是的,感谢您的澄清!
-
如果你在 Java 或 Kotlin 中同时保留接口和 impl 会怎样。那它会编译吗?另外,为什么要使用 JVM 1.8 编译 Kotlin?
-
感谢您的评论。一个全java解决方案编译,而一个全kotlin解决方案总是一个混合项目,因为正如所说的modules-info.java是由javac管理的,所以结果是一样的。另外,我不认为我使用 JVM 1.8 来编译 Kotlin,只是告诉编译器使用 1.8 目标(它是最新可用的);我错了吗?
-
从 Kotlin 版本 1.3.30 开始,您现在可以指定 jvmTarget 9-12。