javakotlinproject-panama

Cant use JEP 434: Foreign Function & Memory API (Second Preview) from kotlin


Do I need to wait until kotlin supports Java 20 bytecode before I can call FFM from my kotlin code? I thought that perhaps since FFM doesnt require any new language features, I could compile with language level 19 and run under Java 20. But I havent been able to get that to work.

To clarify, Ive used jextract to generate a java API to my target C library, then I want to call that from kotlin.

In my gradle file:

tasks {
    val ENABLE_PREVIEW = "--enable-preview"
    withType<JavaCompile>() {
        options.compilerArgs.add(ENABLE_PREVIEW)
        options.compilerArgs.add("-Xlint:preview")
        options.release.set(20)
    }
    withType<Test>().all {
        useJUnitPlatform()
        jvmArgs(ENABLE_PREVIEW)
        minHeapSize = "512m"
        maxHeapSize = "4g"
        systemProperties["junit.jupiter.execution.parallel.enabled"] = "false"
        systemProperties["junit.jupiter.execution.parallel.mode.default"] = "concurrent"
        systemProperties["junit.jupiter.execution.parallel.mode.classes.default"] = "concurrent"
    }
    withType<JavaExec>().all {
        jvmArgs(ENABLE_PREVIEW)
    }
    withType<KotlinCompile> {
        kotlinOptions.jvmTarget = "19"
    }
}

using options.release.set(20) gives error "'compileJava' task (current target is 20) and 'compileKotlin' task (current target is 19) jvm target compatibility should be set to the same Java version."

using options.release.set(19) gives error "Unresolved reference: Arena"

and setting kotlinOptions.jvmTarget = "20" gives "Unknown Kotlin JVM target: 20"

Not sure if theres some workaround? Is it gradle that is interfering or is it the java compiler that insists on not recognizing the preview features without setting the bytecode target to java 20?


Solution

  • Preview features are strongly tied to a particular release. So, if you're using preview features with a Java 20 JVM, only byte code version 20 (i.e. 64) is supported.

    The error that you're seeing when using options.release.set(19) seems to be from gradle using javac's --release flag under the hood, which uses essentially the set of JDK symbols from Java 19 to compile your code against. Arena doesn't exist in JDK 19, hence the error.

    If Kotlin does not support running on Java 20 at the moment, I think your only option for now is to use Java/JDK 19 as well, together with jextract 19, which targets the Java 19 FFM API (https://jdk.java.net/jextract/19/)