[英]Building a Kotlin + Java 9 project with Gradle
我对 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 编译任务上指定模块路径,否则编译会失败:
错误:找不到模块:kotlin.stdlib 需要 kotlin.stdlib;
无论如何,现在这个构建失败并出现这个错误,我不知道如何解决它:
错误:package some.package.impl 不存在
导入 some.package.impl.RoundaboutImpl;
错误:找不到符号
return new RoundaboutImpl<>(queueSize, parallelism, worker, threadPool);
我认为编译的 Kotlin 部分正常,然后 java 部分失败,因为它没有“看到”kotlin 的一面,可以这么说。
我想我应该以某种方式告诉它在类路径中加载已经编译的 kotlin 类; 但是(首先)我如何在 gradle 中执行此操作? 和(第二)甚至可能吗? 我认为你不能在 Java 9 中混合模块路径和 class 路径。
我该如何解决这个问题? 我认为这是一种很常见的情况,因为每个 java9 风格的模块都是混合语言模块(因为module-info.java
),所以我想我在这里遗漏了一些非常基本的东西。
提前致谢!
解决了! 将kotlin编译目录设置为与Java相同的目录就足够了:
compileKotlin.destinationDir = compileJava.destinationDir
现在它可以使用同一棵树或不同树木中的来源; 但有一个怪癖: jar
任务产生一个包含所有条目重复的jar。 接下来,我会努力解决这个问题。
谢谢大家!
我使用以下gradle脚本,我将module-info.java放在src / module下。 它自动包含在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
}
}
}
我不会再更新它,看一下https://github.com/robstoll/atrium/blob/master/build.gradle来查看当前使用的版本。
接受的答案对我不起作用(至少不是它的呈现方式),但这是有效的:
plugins {
id "org.jetbrains.kotlin.jvm" version "1.3.50"
}
compileKotlin {
doFirst {
destinationDir = compileJava.destinationDir
}
}
jar {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
按照接受的答案建议的方式进行操作导致我收到此错误:
为属性“compileKotlinOutputClasses”指定的目录“/path/to/project/build/classes/kotlin/main”不存在。
摇篮版本:5.6
我遇到了同样的问题,现有的答案只为我解决了部分问题,所以我搜索了所有互联网并最终找到了一个可行的解决方案。 我不知道为什么会这样,但我决定在这里分享我的build.gradle.kts
文件来帮助其他人找到他们的方式。 这个文件是我在互联网上找到的许多片段的组合。
我使用的是 Java 16、Kotlin 1.5.31 和 Gradle 7.1。
文件树是:
+ project
- build.gradle.kts
+ src
+ main
+ java
- module-info.java
+ my
+ package
- SomeClasses.java
+ kotlin
+ my
+ package
- MoreClasses.kt
模块信息.java
module name.of.your.javamodule {
requires kotlin.stdlib;
requires kotlinx.coroutines.core.jvm;
requires org.jetbrains.annotations;
exports my.pacakge;
}
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"
}
}
在 gradle 7.4 和 kotlin DSL 上,我需要:
在 build.gradle.kts 中:
val compileKotlin: KotlinCompile by tasks
val compileJava: JavaCompile by tasks
compileKotlin.destinationDirectory.set(compileJava.destinationDirectory)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.