tschuchortdev / kotlin-compile-testing

A library for testing Kotlin and Java annotation processors, compiler plugins and code generation
Mozilla Public License 2.0
670 stars 63 forks source link

Adding `--enable-preview` to `javacArguments` does not work. How to properly do this? #385

Closed GavinRay97 closed 6 months ago

GavinRay97 commented 1 year ago

I'm trying to write an annotation processor which imports java.lang.foreign.MemorySegment from the Panama API's.

My config is:

val result = KotlinCompilation().apply {
    sources = listOf(javaSource, kotlinSource)
    annotationProcessors = listOf(MyAnnotationProcessor())

    inheritClassPath = true
    messageOutputStream = System.out

    javacArguments.add("--enable-preview")
}.compile()

When running this though, I get:

e: /tmp/Kotlin-Compilation15220667380494120571/kapt/sources/com/example/SQLite3HeaderAccessor.java:3: error: MemorySegment is a preview API and is disabled by default.
import java.lang.foreign.MemorySegment;
                        ^
  (use --enable-preview to enable preview APIs)

Is there any way to enable preview API's/does someone have an example of doing this? Thank you! 🙏


It looks like javacOptions is not receiving the --enable-preview flag in kapt, I think:

Javac options: {}

[incremental apt] Changed files: []
[incremental apt] Compiled sources directories: 
[incremental apt] Cache directory for incremental compilation: null
[incremental apt] Changed classpath names: 

i: [kapt] Initial analysis took 1197 ms
i: [kapt] Kotlin files to compile: [SQLite3Header.kt]
i: [kapt] Stubs compilation took 90 ms
i: [kapt] Compiled classes: com/example/SQLite3HeaderKt, com/example/SQLite3HeaderKt$DefaultImpls
i: [kapt] All Javac options: {
    -Akapt.kotlin.generated=/tmp/Kotlin-Compilation15376971212157706383/kapt/kotlinGenerated=-Akapt.kotlin.generated=/tmp/Kotlin-Compilation15376971212157706383/kapt/kotlinGenerated,
    -proc:=only,
    accessInternalAPI=true,
    --class-path=/home/user/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/1.9.0/8ee15ef0c67dc83d874f412d84378d7f0eb50b63/kotlin-stdlib-1.9.0.jar:/home/user/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-common/1.9.0/cd65c21cfd1eec4d44ef09f9f52b6d9f8a720636/kotlin-stdlib-common-1.9.0.jar:/home/user/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jdk8/1.9.0/e000bd084353d84c9e888f6fb341dc1f5b79d948/kotlin-stdlib-jdk8-1.9.0.jar:/home/user/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-reflect/1.6.10/1cbe9c92c12a94eea200d23c2bbaedaf3daf5132/kotlin-reflect-1.6.10.jar:/home/user/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-script-runtime/1.8.0/b2f7e760d283cb339974851c222a4c1d48f2d3d/kotlin-script-runtime-1.8.0.jar:/mnt/c/Users/rayga/.m2/repository/org/junit/platform/junit-platform-launcher/1.10.0/junit-platform-launcher-1.10.0.jar:/mnt/c/Users/rayga/.m2/repository/org/junit/platform/junit-platform-engine/1.10.0/junit-platform-engine-1.10.0.jar:/mnt/c/Users/rayga/.m2/repository/org/opentest4j/opentest4j/1.3.0/opentest4j-1.3.0.jar:/mnt/c/Users/rayga/.m2/repository/org/junit/platform/junit-platform-commons/1.10.0/junit-platform-commons-1.10.0.jar:/mnt/c/Users/rayga/.m2/repository/org/apiguardian/apiguardian-api/1.1.2/apiguardian-api-1.1.2.jar:/mnt/c/Users/rayga/AppData/Local/JetBrains/Toolbox/apps/IDEA-U/ch-0/232.8660.48/lib/idea_rt.jar:/mnt/c/Users/rayga/AppData/Local/JetBrains/Toolbox/apps/IDEA-U/ch-0/232.8660.48/plugins/junit/lib/junit5-rt.jar:/mnt/c/Users/rayga/AppData/Local/JetBrains/Toolbox/apps/IDEA-U/ch-0/232.8660.48/plugins/junit/lib/junit-rt.jar:/home/user/projects/panama-annotation-processor/app/build/classes/kotlin/test:/home/user/projects/panama-annotation-processor/app/build/classes/kotlin/main:/home/user/.gradle/caches/modules-2/files-2.1/com.google.guava/guava/31.1-jre/60458f877d055d0c9114d9e1a2efb737b4bc282c/guava-31.1-jre.jar:/home/user/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-test/1.9.0/eb12bde76a140d37b77a5d1fe4c68abcdc986dc4/kotlin-test-1.9.0.jar:/home/user/.gradle/caches/modules-2/files-2.1/org.junit.jupiter/junit-jupiter/5.10.0/8fea1d9c58b2156f1b998f2f18da04bc9e087f74/junit-jupiter-5.10.0.jar:/home/user/.gradle/caches/modules-2/files-2.1/com.github.tschuchortdev/kotlin-compile-testing/1.5.0/caaaf0a415b4069943b5b9b81903d6ad60d067a9/kotlin-compile-testing-1.5.0.jar:/home/user/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jdk7/1.9.0/f320478990d05e0cfaadd74f9619fd6027adbf37/kotlin-stdlib-jdk7-1.9.0.jar:/home/user/.gradle/caches/modules-2/files-2.1/com.google.guava/failureaccess/1.0.1/1dcf1de382a0bf95a3d8b0849546c88bac1292c9/failureaccess-1.0.1.jar:/home/user/.gradle/caches/modules-2/files-2.1/com.google.guava/listenablefuture/9999.0-empty-to-avoid-conflict-with-guava/b421526c5f297295adef1c886e5246c39d4ac629/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:/home/user/.gradle/caches/modules-2/files-2.1/com.google.code.findbugs/jsr305/3.0.2/25ea2e8b0c338a877313bd4672d3fe056ea78f0d/jsr305-3.0.2.jar:/home/user/.gradle/caches/modules-2/files-2.1/org.checkerframework/checker-qual/3.12.0/d5692f0526415fcc6de94bb5bfbd3afd9dd3b3e5/checker-qual-3.12.0.jar:/home/user/.gradle/caches/modules-2/files-2.1/com.google.errorprone/error_prone_annotations/2.11.0/c5a0ace696d3f8b1c1d8cc036d8c03cc0cbe6b69/error_prone_annotations-2.11.0.jar:/home/user/.gradle/caches/modules-2/files-2.1/com.google.j2objc/j2objc-annotations/1.3/ba035118bc8bac37d7eff77700720999acd9986d/j2objc-annotations-1.3.jar:/home/user/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-test-junit5/1.9.0/f8d6b4256f6e7bd4d7cc0179943eb1534d6e9706/kotlin-test-junit5-1.9.0.jar:/home/user/.gradle/caches/modules-2/files-2.1/org.junit.jupiter/junit-jupiter-params/5.10.0/9041c7365495a897a64782ea5a6fdb99dab1814e/junit-jupiter-params-5.10.0.jar:/home/user/.gradle/caches/modules-2/files-2.1/org.junit.jupiter/junit-jupiter-api/5.10.0/2fe4ba3d31d5067878e468c96aa039005a9134d3/junit-jupiter-api-5.10.0.jar:/home/user/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-compiler-embeddable/1.8.0/eb9118d4bcceaa2a94b2ae2a33a4ddba7c9a947f/kotlin-compiler-embeddable-1.8.0.jar:/home/user/.gradle/caches/modules-2/files-2.1/org.jetbrains/annotations/13.0/919f0dfe192fb4e063e7dacadee7f8bb9a2672a9/annotations-13.0.jar:/home/user/.gradle/caches/modules-2/files-2.1/org.apiguardian/apiguardian-api/1.1.2/a231e0d844d2721b0fa1b238006d15c6ded6842a/apiguardian-api-1.1.2.jar:/home/user/.gradle/caches/modules-2/files-2.1/org.junit.platform/junit-platform-commons/1.10.0/d533ff2c286eaf963566f92baf5f8a06628d2609/junit-platform-commons-1.10.0.jar:/home/user/.gradle/caches/modules-2/files-2.1/org.opentest4j/opentest4j/1.3.0/152ea56b3a72f655d4fd677fc0ef2596c3dd5e6e/opentest4j-1.3.0.jar:/home/user/.gradle/caches/modules-2/files-2.1/io.github.classgraph/classgraph/4.8.156/8c9047eed75496ef1b5dced566b9e23b0c20ecc5/classgraph-4.8.156.jar:/home/user/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-annotation-processing-embeddable/1.8.0/9cfc4599f6c989fba030300f6d04155b645359b3/kotlin-annotation-processing-embeddable-1.8.0.jar:/home/user/.gradle/caches/modules-2/files-2.1/org.junit.jupiter/junit-jupiter-engine/5.10.0/90587932d718fc51a48112d33045a18476c542ad/junit-jupiter-engine-5.10.0.jar:/home/user/.gradle/caches/modules-2/files-2.1/com.squareup.okio/okio-jvm/3.2.0/332d1c5dc82b0241cb1d35bb0901d28470cc89ca/okio-jvm-3.2.0.jar:/home/user/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-daemon-embeddable/1.8.0/d255216c551685dc3a7e852b53617f5f01aaaa5c/kotlin-daemon-embeddable-1.8.0.jar:/home/user/.gradle/caches/modules-2/files-2.1/org.jetbrains.intellij.deps/trove4j/1.0.20200330/3afb14d5f9ceb459d724e907a21145e8ff394f02/trove4j-1.0.20200330.jar:/home/user/.gradle/caches/modules-2/files-2.1/net.java.dev.jna/jna/5.6.0/330f2244e9030119ab3030fc3fededc86713d9cc/jna-5.6.0.jar:/home/user/.gradle/caches/modules-2/files-2.1/org.junit.platform/junit-platform-engine/1.10.0/276c4edcf64fabb5a139fa7b4f99330d7a93b804/junit-platform-engine-1.10.0.jar,
    --processor-path=,
    -s=/tmp/Kotlin-Compilation15376971212157706383/kapt/sources,
    -d=/tmp/Kotlin-Compilation15376971212157706383/classes,
    -encoding=UTF-8
}
tschuchortdev commented 1 year ago

Can you post a minimal example to reproduce this, ideally with the code for logging javac arguments. Also, try javacArguments.addAll("--enable-preview", "-source", "16") since --enable-preview has to be used together with -source or --release, apparently.

GavinRay97 commented 1 year ago

Sure -- thanks for getting back to me.

I've attached a minimal project in a .zip below -- you can get the repro and the debug output containing the kapt params with javac args by running:

./gradlew test --info

Which should print output like:

CLICK TO DISPLAY ```ps1 > Task :lib:test Build cache key for task ':lib:test' is e83b95de97cd64e75eb00ac0e76fea5b Task ':lib:test' is not up-to-date because: Task has failed previously. Watching 46 directories to track changes Watching 41 directories to track changes Watching 40 directories to track changes file or directory '/home/user/projects/panama-annotation-processor/lib/build/classes/java/test', not found Starting process 'Gradle Test Executor 10'. Working directory: /home/user/projects/panama-annotation-processor/lib Command: /home/user/.sdkman/candidates/java/20.0.2-tem/bin/java -Dorg.gradle.internal.worker.tmpdir=/home/user/pr ojects/panama-annotation-processor/lib/build/tmp/test/work -Dorg.gradle.native=false @/home/user/.gradle/.tmp/gradle-worker-classpath11161890201542787179txt -Xmx512m -Dfile.encoding=UTF-8 -Duser.country -Duser.language=en -Duser.variant -ea worker.org.gradle.process.internal.worker.GradleWorkerMain 'Gradle Test Executor 10' Successfully started process 'Gradle Test Executor 10' MyAnnotationProcessorTest > annotation processor test() STANDARD_OUT Starting test logging: Created temporary working directory at /tmp/Kotlin-Compilation16637249140831897634 logging: Inheriting classpaths: v: Using Kotlin home directory v: Using JDK home directory /home/user/.sdkman/candidates/java/20.0.2-tem v: Exception on loading scripting plugin: java.lang.ClassNotFoundException: org.jetbrains.kotlin.scripting.compiler.plugin.ScriptingCompilerConfigurationComponentRegistrar v: Scripting plugin will not be loaded: not all required jars are present in the classpath (missing files: [./kotlin-scripting-compiler.jar, ./kotlin-scripting-compiler-impl.jar, ./kotlinx-coroutines-core-jvm.jar, ./kotlin-scripting-common.jar, ./kotlin-scripting-jvm.jar, ./kotlin-scripting-js.jar, ./js.engines.jar]) v: Using JVM IR backend v: Configuring the compilation environment v: Loading modules: [java.se, jdk.accessibility, jdk.attach, jdk.compiler, jdk.dynalink, jdk.httpserver, jdk.incubator.concurrent, jdk.incubator.vector, jdk.jartool, jdk.javadoc, jdk.jconsole, jdk.jdi, jdk.jfr, jdk.jshell, j dk.jsobject, jdk.management, jdk.management.jfr, jdk.net, jdk.nio.mapmode, jdk.sctp, jdk.security.auth, jdk.security.jgss, jdk.unsupported, jdk.unsupported.desktop, jdk.xml.dom, java.base, java.compiler, java.datatransfer, java. desktop, java.xml, java.instrument, java.logging, java.management, java.management.rmi, java.rmi, java.naming, java.net.http, java.prefs, java.scripting, java.security.jgss, java.security.sasl, java.sql, java.transaction.xa, java.sql.rowset, java.xml.crypto, jdk.internal.jvmstat, jdk.zipfs, jdk.internal.opt, jdk.management.agent, jdk.jdwp.agent, jdk.internal.ed, jdk.internal.le] i: [kapt] Kapt3 is enabled. Annotation processing mode: stubsAndApt Memory leak detection mode: default Show processor stats: false Verbose mode: true Info as warnings: false Use light analysis: true Correct error types: false Dump default parameter values: false Map diagnostic locations: true Strict mode: false Detect annotation processors in compile classpath: true Incremental annotation processing (apt mode): false Strip @Metadata annotations from stubs: false Keep KDoc comments in stubs: true Use JVM IR backend: false Project base dir: null Compile classpath: Java source roots: /tmp/Kotlin-Compilation16637249140831897634/sources/MyClass2.java Sources output directory: /tmp/Kotlin-Compilation16637249140831897634/kapt/sources Class files output directory: /tmp/Kotlin-Compilation16637249140831897634/classes Stubs output directory: /tmp/Kotlin-Compilation16637249140831897634/kapt/stubs Incremental data output directory: /tmp/Kotlin-Compilation16637249140831897634/kapt/incrementalData Annotation processing classpath: Annotation processors: AP options: {kapt.kotlin.generated=/tmp/Kotlin-Compilation16637249140831897634/kapt/kotlinGenerated} Javac options: {} [incremental apt] Changed files: [] [incremental apt] Compiled sources directories: [incremental apt] Cache directory for incremental compilation: null [incremental apt] Changed classpath names: i: [kapt] Initial analysis took 947 ms i: [kapt] Kotlin files to compile: [MyClass1.kt] i: [kapt] Stubs compilation took 107 ms i: [kapt] Compiled classes: panama/annotation/processor/MyClass1 i: [kapt] All Javac options: {-Akapt.kotlin.generated=/tmp/Kotlin-Compilation16637249140831897634/kapt/kotlinGenerated=-Akapt.kotlin.generated=/tmp/Kotlin-Compilation16637249140831897634/kapt/kotlinGenerated, -proc:=only, ac cessInternalAPI=true, --class-path=, --processor-path=, -s=/tmp/Kotlin-Compilation16637249140831897634/kapt/sources, -d=/tmp/Kotlin-Compilation16637249140831897634/classes, -encoding=UTF-8} i: [kapt] Java stub generation took 9 ms i: [kapt] Stubs for Kotlin classes: panama/annotation/processor/MyClass1.java, error/NonExistentClass.java v: Output: /tmp/Kotlin-Compilation16637249140831897634/kapt/stubs/panama/annotation/processor/MyClass1.java Sources: /tmp/Kotlin-Compilation16637249140831897634/sources/MyClass1.kt v: Output: /tmp/Kotlin-Compilation16637249140831897634/kapt/stubs/panama/annotation/processor/MyClass1.kapt_metadata Sources: /tmp/Kotlin-Compilation16637249140831897634/sources/MyClass1.kt v: Output: /tmp/Kotlin-Compilation16637249140831897634/kapt/incrementalData/panama/annotation/processor/MyClass1.class Sources: /tmp/Kotlin-Compilation16637249140831897634/sources/MyClass1.kt v: Output: /tmp/Kotlin-Compilation16637249140831897634/kapt/incrementalData/META-INF/main.kotlin_module Sources: /tmp/Kotlin-Compilation16637249140831897634/sources/MyClass1.kt e: /tmp/Kotlin-Compilation16637249140831897634/sources/MyClass2.java:3: error: MemorySegment is a preview API and is disabled by default. import java.lang.foreign.MemorySegment; ^ (use --enable-preview to enable preview APIs) e: File Object History : [] e: Open Type Names : [] e: Gen. Src Names : [] e: Gen. Cls Names : [] e: Agg. Gen. Src Names : [] e: Agg. Gen. Cls Names : [] ```

kotline-compile-test-repro.zip


I think the issue is here, fwiw: https://github.com/tschuchortdev/kotlin-compile-testing/blob/82ec5425c52e968ae706af0f667d8fe2fe5efdca/core/src/main/kotlin/com/tschuchort/compiletesting/KotlinCompilation.kt#L360-L374

The javac arguments don't seem to be passed through here.

public final class KaptOptions : org.jetbrains.kotlin.base.kapt3.KaptFlags {
   // ...
    public final class Builder public constructor() {
        // ...
        public final val javacOptions: kotlin.collections.MutableMap<kotlin.String, kotlin.String> /* compiled code */

I tried to fork and modify your code, but since javacOptions here expects a Map, I couldn't figure out how to pass arguments that don't expect an -foo=X value like --enable-preview.

GavinRay97 commented 1 year ago

I found a small handful of repos which seem to have --enable-preview being passed to kapt via javacOptions:

kapt {
    javacOptions {
        option("--enable-preview", "")
    }
}
kapt {
    arguments {
        arg("mapstruct.unmappedTargetPolicy", "IGNORE")
    }
    javacOptions {
        option("--enable-preview")
    }
}