簡體   English   中英

用 Gradle 構建一個 Kotlin + Java 9 項目

[英]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 上,我需要:

  • 將 module-info.java 移動到 src/main/java
  • 在每個 package 中創建任何 java 文件以在 src/main/java 下導出,至少為空 package-info.java

在 build.gradle.kts 中:

val compileKotlin: KotlinCompile by tasks
val compileJava: JavaCompile by tasks
compileKotlin.destinationDirectory.set(compileJava.destinationDirectory)

也在這里討論: https://github.com/gradle/gradle/issues/17271

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM