I have this task in my `build.gradle` ```compileKo...
# gradle
v
I have this task in my
build.gradle
Copy code
compileKotlin {
    kotlinOptions {
        jvmTarget = JavaVersion.VERSION_11
    }
}
The IDEA warns me that
kotlinOptions
is deprecated. I can’t find the option how to replace this with a proper syntax. Can anyone please help me? Gradle 7.2, Kotlin 1.8.0
m
Copy code
withType<KotlinCompile> {
    kotlinOptions.jvmTarget = "17"
}
inside
tasks {}
definition
Depend if you have Kotlin or Groovy based build file
v
I have a Groovy based file. I don’t have the
tasks {}
definition. Tasks that I have in the build script are defined on the root level
m
Both are basically doing the same thing.
m
@Vitali Plagov I have
Copy code
compileKotlin {
    kotlinOptions.jvmTarget = '17'
}
In another project without warning
m
It might be that the IDEA warning cannot detect all possible syntax
v
@mudasar187 thank you, that removed the deprecation warning. Though, it looks very much the same
m
But if it complains about
kotlinOptions
in one of the syntax above, I'm pretty sure it should be the case for all other syntaxes that use
kotlinOptions
, whether you use Groovy, Kotlin,
withType
or
compileKotlin
, etc...
v
Indeed
Could be an IDEA issue or a bug?
m
Sounds like an IDEA issue
But in Groovy TBH it's really hard to do this kind of inspections
This is one of the reasons I like Kotlin build scripts better
v
We have a very simple gradle build script, so I still didn’t find enough justification to convert it to the Kotlin syntax 🙂
t
Heh, it is deprecation of this method you are seeing:
Copy code
fun kotlinOptions(fn: Closure<*>) { ... }
Generally it is not related to
compilerOptions
, but still you should to migrate to them.
kotlinOptions
will be deprecated once IDEA will have proper support for migration from
kotlinOptions
m
Ah ! So the syntax was important actually. Thanks, TIL!
v
Which option would be better instead of the deprecated one then?
Copy code
compileKotlin {
    kotlinOptions.jvmTarget = '17'
}
this?
t
I would say better to use:
Copy code
compileKotlin {
    compilerOptions.jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17
}
m
@tapchicoma is this for groovy based or also for Kotlin DSL?
t
Kotlin DSL will be:
Copy code
tasks.named<org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile>("compileKotlin") {
    compilerOptions.jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17)
}
obviously will look better with imports 🙂
v
Is there no type-safe accessor? So
tasks.compileKotlin { compilerOptions... }
for Kotlin DSL.
t
there is, but it uses internal KGP task type which we are planning to hide 🤔
probably still ok
c
Is there another variant of this for when using the Kotlin Multiplatform Gradle plugin? When just trying this as-is, I get
Copy code
* What went wrong:
Task with name 'compileKotlin' not found in project ':app'.
m
On multiplatform, compile tasks have the target name inside like
compileKotlinJvm
or so. You can certainly apply to all tasks. Maybe something like this:
Copy code
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>() {
    compilerOptions.jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17)
}
Modulo lazy configuration, etc...
v
Please don't use
tasks.withType<...>() { ... }
but
tasks.withType<...>().configureEach { ... }
or all tasks of that type get realized and configured prematurely instead only when needed.
m
Yep, that ☝️ . Thank @Vampire
c
Thanks—I got that to work and learned something new with the
configureEach
. Related, how does one get the output of the build to target older JVM versions while building with newer JVM versions? I currently get this build warning if I use toolchains.
Copy code
'compileJava' task (current target is 17) and 'compileKotlinJvm' task (current target is 11) jvm target compatibility should be set to the same Java version.
By default will become an error since Gradle 8.0+! Read more: <https://kotl.in/gradle/jvm/target-validation>
Consider using JVM toolchain: <https://kotl.in/gradle/jvm/toolchain>
v
Did you have a look at those links?
m
Use a toolchain 🤓
c
Yes but means dropping to a Java 11 toolchain to generate Java 11 output, right?
m
You can use a Java19 toolchain and set the target to 11
c
But then you get the warning I just mentioned above.
So I’m trying to figure out how to use a newer toolchain but emit class files compatible with older JVMs.
v
The question is why you should do so. You usually set a toolchain and not configure a target version. That's why you set a toolchain. It uses that toolchain and produces bytecode for that toolchain.
Why do you want to use a newer toolchain but configure an older target?
m
It makes sense to use latest toolchain (for faster GC for an example) but still set target version (for compatibility with older runtimes)
c
What Martin says, but also there’s a historical example.
m
We do something like this
Copy code
project.tasks.withType(JavaCompile::class.java).configureEach {
    options.release.set(11)
  }
c
Historical example: Last year, it was very problematic because there weren’t Apple Silicon compatible toolchains for Java 11 but there were for Java 17.
But to run on a hosted server platform, our output needed to run on Java 11.
v
Hm, I see. Then probably what Martin said. 🙂
c
Thank you both 🙂
e
there's a
kotlin
extension which can be used instead of configuring the tasks. for
org.jetbrains.kotlin.jvm
plugin,
Copy code
kotlin.target.compilations.all {
    kotlinOptions.jvmOptions = "11"
}
for
org.jetbrains.kotlin.multiplatform
plugin,
Copy code
kotlin.targets.all {
    compilations.all {
        (kotlinOptions as? KotlinJvmOptions)?.jvmOptions = "11"
    }
}
c
I think that’s deprecated now, right?
e
but also setting the Java toolchain will set Kotlin's JVM target by default
as far as I know, only
freeCompilerArgs
is being deprecated
t
Last year, it was very problematic because there weren’t Apple Silicon compatible toolchains for Java 11 but there were for Java 17.
SDKMAN should provide such toolchains for Mac silicon and then Gradle will auto detect them. With Gradle 7.6 probably this plugin will auto-provision toolchains for Apple silicon.
c
The Apple Silicon problem is partially solved now, as adoptium has a java 11 JDK now and Gradle should fetch that. So its fine as long as no one needs to target Java 8 😬
1875 Views