I'm looking into migrating a Groovy codebase to Ko...
# gradle
r
I'm looking into migrating a Groovy codebase to Kotlin. I was doing OK with having the Kotlin code depend on the Groovy code, but after some thought I think the migration will be easier if the Groovy code depends on the Kotlin code. I'm struggling to get
compileGroovy
to see the Kotlin classes though. Could anyone give me some pointers?
For reference, this was the
build.groovy
config I used to get Kotlin depending on Groovy:
Copy code
tasks.named('compileGroovy') {
    // Groovy only needs the declared dependencies
    // (and not longer the output of compileJava)
    classpath = sourceSets.main.compileClasspath
}

tasks.named('compileKotlin') {
    // Kotlin also depends on the result of Groovy compilation
    // (which automatically makes it depend of compileGroovy)
    classpath += files(sourceSets.main.groovy.classesDirectory)
}

tasks.named('compileTestGroovy') {
    // Groovy only needs the declared dependencies
    // (and not longer the output of compileJava)
    classpath = sourceSets.test.compileClasspath
}

tasks.named('compileTestKotlin') {
    // Kotlin also depends on the result of Groovy compilation
    // (which automatically makes it depend of compileGroovy)
    classpath += files(sourceSets.test.groovy.classesDirectory)
}
a
how do you access the Kotlin classes? Just in case you weren’t aware, many classes (only exception is kotlin files with a single class with the same name as the file) will get a “Kt” suffix
r
The classes have the correct names. The problem is that the Kotlin classes are not on the Groovy compile classpath.
I presume I need something along the lines of:
Copy code
tasks.named('compileGroovy') {
    classpath = [
        sourceSets.main.compileClasspath,
        sourceSets.main.kotlin.classesDirectory
    ]
}
but
classesDirectory
is not a property of
sourceSets.main.kotlin
.
v
There is an example of how to change the lanugage dependency order in the manual
It is for changing the order between Groovy and Java, but I guess for Groovy and Kotlin it should be largely the same.
Ah now I see your problem. There is no source directory set named "kotlin" like for "groovy"
r
Insofar as I understand that page, it would mean this:
Copy code
tasks.named('compileKotlin') {
    classpath = sourceSets.main.compileClasspath
}

tasks.named('compileGroovy') {
    classpath += files(sourceSets.main.kotlin.classesDirectory)
}
but
sourceSets.main.kotlin.classesDirectory
doesn't seem to exist.
What you said
v
Try it with
.java.
instead of
.kotlin.
. Iirc, that's the way to go.
r
compileGroovy
is still reporting
unable to resolve class XXX
for all my Kotlin classes. A
build/classes/kotlin
directory exists with my compiled Kotlin classes, so I guess
compileKotlin
does have its own independent output? Or would it have added it to
sourceSets.main.java.classesDirectory
? I do find it hard to navigate the Gradle model to work out what to do in these circumstances. Unfortunately googling anything involving the words gradle, groovy and kotlin inevitably brings up reams of results about the gradle DSL.
The following seems to work:
Copy code
tasks.named('compileGroovy') {
    classpath += files(tasks.compileKotlin.destinationDir)
}
(The task dependencies are already correct, as Groovy depends on Java and Java depends on Kotlin)
Oh no, that only worked with Kotlin 1.6... 1.7 doesn't have
tasks.compileKotlin.destinationDir
.
OK, so with Kotlin 1.7 (& gradle 7.5.1) this works:
Copy code
tasks.named('compileGroovy') {
    classpath += files(tasks.compileKotlin.destinationDirectory)
}

tasks.named('compileTestGroovy') {
    classpath += files(tasks.compileTestKotlin.destinationDirectory)
}
If this is wrong™ please let me know.