[英]Building a Kotlin + Java 9 project with Gradle
I'm fairly new to Gradle (and Java 9, to be honest), and I'm trying to use Gradle to build a simple library project that is a mix of Java 9 and Kotlin. More in detail, there is an interface in Java and an implementation in Kotlin;我对 Gradle(和 Java 9,老实说)还很陌生,我正在尝试使用 Gradle 构建一个简单的库项目,该项目混合了 Java 9 和 Kotlin。更详细地说,有一个接口Java 和 Kotlin 中的实现; I'd do everything in Kotlin, but the
modules-info.java
is java anyway, so I decided to do things this way.我会在 Kotlin 中做所有事情,但是
modules-info.java
无论如何都是 java,所以我决定这样做。
I'm building on IntelliJ Idea, with the 1.2.0 kotlin plugin and gradle 4.3.1 defined externally.我在 IntelliJ Idea 上构建,使用外部定义的 1.2.0 kotlin 插件和 gradle 4.3.1。
Filesystem schema is:文件系统架构是:
+ src
+ main
+ java
+ some.package
- Roundabout.java [an interface]
- module-info.java
+ kotlin
+ some.package.impl
- RoundaboutImpl.kt [implementing the interface]
module-info.java
is: module-info.java
是:
module some.package {
requires kotlin.stdlib;
exports some.package;
}
and build.gradle
is: 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"
}
Notice that I had to specify a module path on the java compile task, or the compilation fails with:请注意,我必须在 java 编译任务上指定模块路径,否则编译会失败:
error: module not found: kotlin.stdlib requires kotlin.stdlib;
错误:找不到模块:kotlin.stdlib 需要 kotlin.stdlib;
Anyway, now this build fails with this error, and I can't figure out how to solve it:无论如何,现在这个构建失败并出现这个错误,我不知道如何解决它:
error: package some.package.impl does not exist
错误:package some.package.impl 不存在
import some.package.impl.RoundaboutImpl;
导入 some.package.impl.RoundaboutImpl;
error: cannot find symbol
错误:找不到符号
return new RoundaboutImpl<>(queueSize, parallelism, worker, threadPool);
return new RoundaboutImpl<>(queueSize, parallelism, worker, threadPool);
I think that the Kotlin part of the compilation is going ok, then the java part fails because it doesn't "see" the kotlin side, so to speak.我认为编译的 Kotlin 部分正常,然后 java 部分失败,因为它没有“看到”kotlin 的一面,可以这么说。
I think I should tell it somehow to to load the already compiled kotlin classes in the classpath;我想我应该以某种方式告诉它在类路径中加载已经编译的 kotlin 类; but (first) how do I do this in gradle?
但是(首先)我如何在 gradle 中执行此操作? and (second) is it even possible ?
和(第二)甚至可能吗? I think you can't mix module path and class path in Java 9.
我认为你不能在 Java 9 中混合模块路径和 class 路径。
How can I solve this?我该如何解决这个问题? I think it is a pretty common situation, as every java9-style module will be a mixed-language module (because of
module-info.java
), so I think I'm missing something really basic here.我认为这是一种很常见的情况,因为每个 java9 风格的模块都是混合语言模块(因为
module-info.java
),所以我想我在这里遗漏了一些非常基本的东西。
Thanks in advance!提前致谢!
Solved! 解决了! It was sufficient to set the kotlin compilation dir to the same dir as Java:
将kotlin编译目录设置为与Java相同的目录就足够了:
compileKotlin.destinationDir = compileJava.destinationDir
It works now, both with the sources in the same tree or in different trees; 现在它可以使用同一棵树或不同树木中的来源; but with a quirk: the
jar
task produces a jar with all the entries duplicated. 但有一个怪癖:
jar
任务产生一个包含所有条目重复的jar。 I'll work on fix this, next. 接下来,我会努力解决这个问题。
Thanks to everyone! 谢谢大家!
I am using the following gradle script where I put the module-info.java under src/module. 我使用以下gradle脚本,我将module-info.java放在src / module下。 It gets automatically included in the jar (without duplicates):
它自动包含在jar中(没有重复):
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
}
}
}
I won't update it any longer, have a look at https://github.com/robstoll/atrium/blob/master/build.gradle to see the current version in use. 我不会再更新它,看一下https://github.com/robstoll/atrium/blob/master/build.gradle来查看当前使用的版本。
The accepted answer did not work for me (atleast not the way it was presented), but this is what worked:接受的答案对我不起作用(至少不是它的呈现方式),但这是有效的:
plugins {
id "org.jetbrains.kotlin.jvm" version "1.3.50"
}
compileKotlin {
doFirst {
destinationDir = compileJava.destinationDir
}
}
jar {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
Doing it the way the accepted answer suggests led to me getting this error:按照接受的答案建议的方式进行操作导致我收到此错误:
Directory '/path/to/project/build/classes/kotlin/main' specified for property 'compileKotlinOutputClasses' does not exist.
为属性“compileKotlinOutputClasses”指定的目录“/path/to/project/build/classes/kotlin/main”不存在。
Gradle version : 5.6摇篮版本:5.6
I ran into the same problem and the existing answers fixed only part of the issue for me, so I searched over all internet and ended up with a working solution.我遇到了同样的问题,现有的答案只为我解决了部分问题,所以我搜索了所有互联网并最终找到了一个可行的解决方案。 I don't know exactly why this works, but I decided to share my
build.gradle.kts
file here to help other people to find they way.我不知道为什么会这样,但我决定在这里分享我的
build.gradle.kts
文件来帮助其他人找到他们的方式。 This file is a combination of many pieces that I found on the internet.这个文件是我在互联网上找到的许多片段的组合。
I'm using Java 16, Kotlin 1.5.31 and Gradle 7.1.我使用的是 Java 16、Kotlin 1.5.31 和 Gradle 7.1。
The file tree is:文件树是:
+ project
- build.gradle.kts
+ src
+ main
+ java
- module-info.java
+ my
+ package
- SomeClasses.java
+ kotlin
+ my
+ package
- MoreClasses.kt
module-info.java模块信息.java
module name.of.your.javamodule {
requires kotlin.stdlib;
requires kotlinx.coroutines.core.jvm;
requires org.jetbrains.annotations;
exports my.pacakge;
}
build.gradle.kts build.gradle.kts
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
application
kotlin("jvm") version "1.5.31"
id("org.jetbrains.kotlin.plugin.serialization") version "1.5.31"
}
val kotlinVersion = "1.5.31"
group = "your.group.id"
version = "0.0.1-SNAPSHOT"
application {
mainClass.set("full.name.of.your.MainClass")
mainModule.set("name.of.your.javamodule") // Same defined in module-info.java
executableDir = "run"
}
repositories {
mavenCentral()
}
dependencies {
implementation(kotlin("stdlib-jdk8", kotlinVersion))
implementation("com.michael-bull.kotlin-inline-logger:kotlin-inline-logger:1.0.3")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2-native-mt")
implementation("org.jetbrains:annotations:22.0.0")
testImplementation(kotlin("test", kotlinVersion))
}
java {
sourceCompatibility = JavaVersion.VERSION_16
targetCompatibility = JavaVersion.VERSION_16
}
tasks {
run.configure {
dependsOn(jar)
doFirst {
jvmArgs = listOf(
"--module-path", classpath.asPath
)
classpath = files()
}
}
compileJava {
dependsOn(compileKotlin)
doFirst {
options.compilerArgs = listOf(
"--module-path", classpath.asPath
)
}
}
compileKotlin {
destinationDirectory.set(compileJava.get().destinationDirectory)
}
jar {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
}
tasks.withType<KotlinCompile>().configureEach {
kotlinOptions {
jvmTarget = "16"
}
}
On gradle 7.4 with kotlin DSL, I need to:在 gradle 7.4 和 kotlin DSL 上,我需要:
In build.gradle.kts:在 build.gradle.kts 中:
val compileKotlin: KotlinCompile by tasks
val compileJava: JavaCompile by tasks
compileKotlin.destinationDirectory.set(compileJava.destinationDirectory)
Also discussed here: https://github.com/gradle/gradle/issues/17271也在这里讨论: https://github.com/gradle/gradle/issues/17271
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.