javakotlingradlegradle-kotlin-dslsource-sets

Mix Java and Kotlin in Gradle Kotlin DSL with sourceSet


I have a project that mixes Java and Kotlin.

The Java code in src/main/java calls Kotlin code in src/main/kotlin. The app is launched from the Kotlin part.

In the build.gradle.kts, the full content

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
    java
    id("project-report")
    id("org.springframework.boot") version "3.2.4"
    id("io.spring.dependency-management") version "1.1.4"
    kotlin("jvm") version "1.9.23"
    kotlin("plugin.spring") version "1.9.23"
}

group = "com.aaaaa"
version = "x.y.z-SNAPSHOT"


sourceSets {

    // https://stackoverflow.com/questions/38131237/mixing-java-and-kotlin-in-gradle-project-kotlin-cannot-find-java-class
    main {
        java.srcDirs("src/main/java","src/main/kotlin") 
        kotlin.srcDir("src/main/java")
    }
}


java {
    sourceCompatibility = JavaVersion.VERSION_17
    targetCompatibility = JavaVersion.VERSION_17
}


repositories {
    mavenCentral()
}

dependencies {
    implementation("org.springframework.boot:spring-boot-starter-thymeleaf")
    implementation("org.springframework.boot:spring-boot-starter-web")
    implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
    implementation("org.jsoup:jsoup:1.17.2")
    implementation("io.github.jbock-java:either:1.5.2")
    implementation("org.jetbrains.kotlin:kotlin-reflect")
    implementation("org.htmlunit:htmlunit:4.2.0")

    developmentOnly("org.springframework.boot:spring-boot-devtools")
    testImplementation("org.springframework.boot:spring-boot-starter-test")
    testImplementation ("org.junit.jupiter:junit-jupiter-api:5.8.1")
//  testRuntimeOnly ("org.junit.jupiter:junit-jupiter-engine:5.8.1")
}


tasks.withType<KotlinCompile> {
    kotlinOptions {
        freeCompilerArgs += "-Xjsr305=strict"
        jvmTarget = "17"
    }
}

tasks.withType<Test> {
    useJUnitPlatform()
}

The Java code cannot find Kotlin code and I get this error during the build ./gradlew build:

Execution failed for task ':compileJava'.
Compilation failed;

Strange thing, everything was working without explicitly sourceSets in Gradle before I updated to IntelliJ 2024.

What is wrong in the sourceSets configuration in order for the Java code to find Kotlin code? The app is launched from Kotlin part.

I read Building a Kotlin + Java 9 project with Gradle

The solution is to set the kotlin compilation directory to the same directory as Java:

compileKotlin.destinationDir = compileJava.destinationDir

This line is invalid in Gradle 8.7 Kotlin DSL.

Rant : Seriously why the Gradle team keeps changing the API in the same DSL language.


Solution

  • I wasn't looking at the right place.

    I had module files. I deleted them

    src/main/java/module-info.java
    src/test/java/module-info.java
    

    Basically src/main/java/module-info.java require import of each library. However I could not find a way to import src/main/kotlin.

    By deleting modules , it fixed.

    Thanks everyone for your answers and comments, my build.gradle.kts had these configurations implictly. By setting sourceSets , now the build explicitly targets these directories.

    Anyone who encounters a trouble with in a single project mixing Java and Kotlin. Check if you have module-info.java versioned.