0

I have a backend service written in Java using Spring Boot as a framework and with help of Lombok as an annotation processor (to generate boilerplate code) that I build using Gradle. I would like to introduce Kotlin into that service in an incremental and quite conservative way. Namely, I would like to rewrite controllers, when opportunity appears, then the code that is used by those controllers and so on downwards the call stack, until whole service is rewritten. Also, I would like to keep strict dependency rule: in no way would my Java code call Kotlin code.

In regard to Gradle, I would like my Java code to be compiled first and only by Java compiler. I don't want the Kotlin compiler to touch this code, but only to rely on compiled classes. I tried to use Kotlin plugin for Gradle (org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.21) but it affects my build in such a way that task compileKotlin appears first

    Found task graph: org.gradle.execution.taskgraph.DefaultTaskExecutionGraph@782f578b
Found 29 tasks.
task ':compileKotlin'
task ':compileJava'

I would like it to be more like

task ':compileJava'
task ':compileKotlin'

Can I establish the order of compilation tasks such that Java is compiled first in a single-module Gradle project? Is making two separate modules the only choice available?

1 Answers1

0

No, it's not possible to compile Java first in a single module. You can try this SO answer to show the dependency tree of a project. The task compileJava does depend on compileKotlin:

:app:build
+--- :app:assemble
|    +--- :app:distTar
|    |    +--- :app:jar
|    |    |    +--- :app:classes
|    |    |    |    +--- :app:compileJava
|    |    |    |    |    \--- :app:compileKotlin
|    |    |    |    \--- :app:processResources
|    |    |    +--- :app:compileKotlin *
|    |    |    \--- :app:inspectClassesForKotlinIC
|    |    |         +--- :app:classes *
|    |    |         \--- :app:compileKotlin *
|    |    \--- :app:startScripts
|    |         \--- :app:jar *
|    +--- :app:distZip
|    |    +--- :app:jar *
|    |    \--- :app:startScripts *
|    \--- :app:jar *
\--- :app:check
     \--- :app:test
          +--- :app:classes *
          +--- :app:compileKotlin *
          +--- :app:compileTestKotlin
          |    +--- :app:classes *
          |    +--- :app:compileKotlin *
          |    \--- :app:jar *
          \--- :app:testClasses
               +--- :app:compileTestJava
               |    +--- :app:classes *
               |    +--- :app:compileKotlin *
               |    \--- :app:compileTestKotlin *
               \--- :app:processTestResources

Also, mixing Java and Kotlin code will make Lombok annotations useless. You can try to access a Lombok-annotated POJO from Kotlin code.

I faced the same problem before, and I had to choose the multi-module solution. However, it's not a poor decision because the build.gradle.ktss are much cleaner.

chehsunliu
  • 1,559
  • 1
  • 12
  • 22
  • Thanks. In the meantime I tried to hack into Jetbrains plugin to create my own task and invoke Kotlin compiler in it. Without much success. Can't say it is impossible but, well it is hacking the tool. – jarek.wolf Oct 02 '21 at 15:08