Hi, does anyone know why I am not able to compile ...
# gradle
k
Hi, does anyone know why I am not able to compile my kotlin code targeting jvm 11 when using
kotlin-dsl
plugin. I have tried setting
jvmTarget
for
KotlinCompile
task:
Copy code
withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
    kotlinOptions.jvmTarget = "11"
}
or like this:
Copy code
kotlinDslPluginOptions {
    jvmTarget.set("11")
}
setting toolchain like this:
Copy code
kotlin.jvmToolchain {
    (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(11))
}
but when I add
kotlin-dsl
to plugins then code doesn't compile because of API I used from java 9, so it seems like it still uses jvm 8. Without
kotlin-dsl
everything builds fine.
c
The Kotlin DSL compiler unfortunately uses an afterEvaluate block to setup its options, thereby overriding what you set. If you wish to configure it you can use something like this:
Copy code
afterEvaluate {
            tasks.withType<KotlinCompile>().configureEach {
   }
}
Note: use of
afterEvaluate
is generally discouraged. This is a special case as it is the only way to override what the plugin does (ideally it should not be using afterEvaluate).
Also, note that with Gradle 8 the Kotlin DSL plugin uses the configured JVM toolchain directly.
e
also, as Gradle supports running on Java 8, consider making your plugins support running on Java 8 as well. that's why it's set up that way
k
In source code it looks like it should pick up the version I have configured:
Copy code
if (this@kotlinDslPluginOptions.jvmTarget.isPresent) {
    jvmTarget.set(JvmTarget.fromTarget(this@kotlinDslPluginOptions.jvmTarget.get()))
}
c
That source is Gradle 8, is that what you are using? Previous versions didn’t have that snippet.
k
I am using gradle 7.4.2 and it has similar code:
Copy code
it.kotlinOptions {
    jvmTarget = this@kotlinDslPluginOptions.jvmTarget.get()
    ...
}
And unfortunately configuring it in
afterEvaluate
doesn't help.
c
It does work using afterEvaluate. Will need to track down pre-Gradle 8 code snippet…
Prior to Gradle 8 this snippet can be used to set the JVM version for the Kotlin DSL plugin:
Copy code
configure<KotlinDslPluginOptions> {
    jvmTarget.value = "17"
}
Setting kotlinOptions can be done with this snippet:
Copy code
// afterEvaluate required as kotlin dsl plugin sets its defaults in afterEvaluate
// <https://github.com/gradle/gradle/blob/master/subprojects/kotlin-dsl-plugins/src/main/kotlin/org/gradle/kotlin/dsl/plugins/dsl/KotlinDslCompilerPlugins.kt#L43>
afterEvaluate {
    tasks.withType<KotlinCompile>().configureEach {
        kotlinOptions {
            
        }
    }
}
If you are only setting the JVM version (and not other Kotlin compiler options) then only the first snippet is needed.
k
When I set breakpoint here:
Copy code
jvmTarget = this@kotlinDslPluginOptions.jvmTarget.get()
then
jvmTarget
is set to "11" indeed but somehow my code still doesn't compile.
c
then this isn’t your issue. what is the error message you are encountering?
k
It is just
Unresolved reference: newDefaultInstance
and whole source code is:
Copy code
fun main(args: Array<String>) {
    TransformerFactory.newDefaultInstance()
}
newDefaultInstance
method is from java 9
c
hmmm. odd to see
fun main(args: Array<String>)
in a kotlin-dsl project, which is by definition creating a Gradle plugin, not otherwise executable Kotlin code.
e
jvmTarget does not affect which Java classpath you're compiling with, only what the target bytecode level is
your issue is something else
aha, I see what you're doing
c
are you creating a Gradle plugin? If not, you want
kotlin("jvm")
instead of
kotlin-dsl
.
e
the Gradle API JAR has its own copy of the java.xml module
you will not be able to use the JVM's own java.xml APIs in any Gradle plugin
(even if you fix the compile issue, it will not work at runtime)
k
I use both
kotlin("jvm")
and
kotlin-dsl
in gradle plugin source code. Previous code is only for testing against smaller source code.
e
c
while perhaps not related to this issue it’s problematic to use both kotlin(“jvm”) and kotlin-dsl. The former is for a Kotlin app/library, the latter is for a Gradle plugin. Using both together introduces a number of issues.
e
this is not a Kotlin issue, although earlier versions of Java did have a bug that made the compile work (even though it shouldn't)
this is an issue with anything that uses
dependencies { implementation(gradleApi()) }
(and also anything loaded into Gradle's classpath at runtime)
k
even when I got rid of
kotlin("jvm")
and left only
kotlin-dsl
it doesn't work
e
yes. it's not a Kotlin issue, it's a Gradle issue, as I said.
any
java.xml
API newer tha Java 8 is simply not going to work, regardless of which Java you're building or running Gradle with
k
ohh ok thank you guys