Kotlin K2 Support
mgroth0 opened this issue · comments
Testing Problem
I am testing with Kotlin K2 (Kotlin version 2.0.0-Beta2). I just discovered jqwik and wanted to play around with it and consider integrating it into my projects. The docs for kotlin say to include these compiler arguments:
tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs = listOf(
"-Xjsr305=strict", // For strict type warnings
"-Xemit-jvm-type-annotations" // Required for annotations on type variables
)
jvmTarget = "11" // 1.8 or above
javaParameters = true // Required to get correct parameter names in reporting
}
}
I tried to add the two compiler arguments above, but then got the following warnings:
w: Flag is not supported by this version of the compiler: -Xjsr305=strict
w: Flag is not supported by this version of the compiler: -Xemit-jvm-type-annotations
This signals to me that jqwik does not yet have first class support for Kotlin 2, so I am hesitating to use it for now.
Suggested Solution
I suggest to add support for Kotlin 2. The documentation could be updated to say how the user should configure kotlin if they use K2, which would also reasure the user that K2 is supported.
I guess the mentioned flags are outdated, and they should be removed
K2 is still in beta with the latest Kotlin release (1.9.22), isn't it.
My plan is to update to K2 as soon as it is the default, which I assume will be in Kotlin 2.0.
What if we use this issue to document the problems with K2 and the stuff that has to be changes, like dropping some compiler flags - and maybe adding others.
BTW, @mgroth0 What's the correct way to use K2 from Gradle with the current Kotlin release?
See https://kotlinlang.org/docs/whatsnew19.html#try-the-k2-compiler-in-your-project
./gradlew -Pkotlin.experimental.tryK2=true ...
Thanks @vlsi .
A first try leads to many compilation errors. Arrgh.
The majority of compilation errors are caused by jsr305
annotations.
WDYT of completely removing jsr305
from jqwik?
For instance, https://github.com/jqwik-team/jqwik/blob/main/api/src/main/java/net/jqwik/api/NonNullApi.java effectively marks everything as non-null no matter if you specify it with jspecify.
I think you should be able to drop @NonNullApi
(along with jsr305
dependency), and add @NullMarked
at the package level: https://jspecify.dev/docs/user-guide#java-variables-are-references
At least worth a try.
Thank you both for looking into this and for giving K2 a shot.
I've been working with K2 for a month or so now. It's still unstable, and I've had to create workarounds for many issues. Sorry for dumping this on you guys. It might be smart to wait a few more months at least. I expect Jetbrains will have resolved many more issues by then.
jsr305 removal makes sense even without K2
Kotlin 2.0 has been released yesterday: https://kotlinlang.org/docs/whatsnew20.html
That somehow strongly suggests to migrate to K2 with jqwik 1 rather sooner than later. I had hoped to defer that till version 2 :-/
Published in 1.9.0-SNAPSHOT
Could be just me, but it seems like -Xjsr305 property is still respected by the final version of the compiler.
Also, just wanted to check if always targetting the latest version of kotlin is intended? I assume that regardless of how good Kotlin devs are, some may obstain from updating to it immediately. So maybe setting a kotlinTarget to 1.9 would be a good idea?
Could be just me, but it seems like -Xjsr305 property is still respected by the final version of the compiler.
Since jsr305 is no longer used this shouldn't affect jqwik's Kotlin module. But maybe I'm missing something.
Also, just wanted to check if always targetting the latest version of kotlin is intended? I assume that regardless of how good Kotlin devs are, some may obstain from updating to it immediately. So maybe setting a kotlinTarget to 1.9 would be a good idea?
Frankly, I find the current state of how to set minimum and compilation versions of Kotlin in Gradle highly confusing. I just cannot find documentation that describes it sufficiently for me.
Anyways, I tried to set min target version to 1.9 and released it as a snapshot (`1.9.0-SNAPSHOT'). See e5ac104.
You might want to try it out.
Anything missing from K2 support that should go into the next release?
It looks good, however, it is worth adding -Xjdk-release=...
(~ https://github.com/jqwik-team/jqwik/blob/207f5f067b67ee2cbd6133c769d375f10436ce23/kotlin/build.gradle#L87C36-L87C58) to avoid cases like https://www.morling.dev/blog/bytebuffer-and-the-dreaded-nosuchmethoderror/
I guess adding "-Xjdk-release=${javaTargetVersion}"
to freeCompilerArgs
should do the trick.
I guess adding
"-Xjdk-release=${javaTargetVersion}"
tofreeCompilerArgs
should do the trick.
Fails for Java 8 with
Error: Execution failed for task ':kotlin:compileKotlin'.
A failure occurred while executing org.jetbrains.kotlin.compilerRunner.GradleCompilerRunnerWithWorkers$GradleKotlinCompilerWorkAction
Compilation error. See log for more details
which is not very informative since the available logs do not seem to provide more information
Failing run: https://github.com/jqwik-team/jqwik/actions/runs/9609449124/job/26503957069
See https://github.com/jqwik-team/jqwik/actions/runs/9609449124/job/26503957069#step:5:253
e: '-Xjdk-release=8' option is not supported by used JDK: C:\hostedtoolcache\windows\Java_Zulu_jdk\8.0.412-8\x64
Ideally, I would suggest using a recent JDK (e.g. Java 17) for the build purpose via JDK toolchains, and use older Java for testing purpose only.
As a workaround, you could skip adding Xjdk-release
if running with Java 8.
Using toolchains would be the preferred way - if I had the time to look into the best way to do it.
I hacked around it by not using the compiler option on JDK 8. CI works now.
For some reason unknown to me, I can no longer publish a snapshot to a 401. Hopefully that's temporary.
Managed to publish 1.9.0-SNAPSHOT
.