Search code examples
kotlingradlegroovymigration

How do I make Gradle 8+ compile Groovy code before Kotlin code? and mix them in one project?


Using a very recent version of gradle (8.5) I want to compile Groovy code before Kotlin code. This will enable me to gradually migrate the entire project from Groovy to Kotlin using a top-down approach. (i.e., migrate one controller to Kotlin while the underlying dependencies remain in Groovy).

The Kotlin gradle plugin seems to update the task requirements, forcing the Kotlin compilation to happen first.

  • Kotlin plugin wants to happen after the compileJava
  • Groovy plugin wants to perform compileJava first Thus, I can't do a compileGroovy without it triggering a compileKotlin which prevents my goal from above.

TaskTree ouptut:

:compileGroovy
\--- :compileJava
     \--- :compileKotlin
          \--- :checkKotlinGradlePluginConfigurationErrors

plugins used in build.gradle:

plugins {
    id 'groovy'
    id 'application'
    id 'org.jetbrains.kotlin.jvm' version '2.0.0-Beta2'
    id "com.dorongold.task-tree" version "2.1.1"
    id 'idea'
}

Steps to reproduce:

  1. place a Groovy class file in src/main/groovy (i.e., Author)
  2. place a Kotlin class file in src/main/kotlin that depends on that Groovy class. (i.e., Book)

Additional research notes:


Solution

  • The base idea of the documentation at https://docs.gradle.org/current/userguide/building_java_projects.html#sub:compile_deps_jvm_lang and thus the solution in Gradle 6+ : compile groovy before kotlin you posted stays the same.

    You remove the groovy => java dependency and add a kotlin => groovy dependency.

    That the linked answer does not literally work has nothing to do with Gradle 6 vs. Gradle 8.

    Your problem is Kotlin Gradle Plugin <1.8 vs. >=1.8 as in 1.8 the deprecated classpath property was finally made an error and later removed, in favor of libraries.

    So here the version of the configuration that works with your version as Kotlin DSL snippet:

    tasks.compileGroovy {
        classpath = sourceSets.main.get().compileClasspath
    }
    
    tasks.compileKotlin {
        libraries.from(sourceSets.main.get().groovy.classesDirectory)
    }