Compatibilité JVM de Gradle : comment faire cohabiter Kotlin 1.8 et Java 11

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Pourquoi votre projet Kotlin et Java s'effondre-t-il soudainement ?

\n\n

Avez-vous déjà été confronté à une situation où vous écrivez du code en Kotlin, utilisez Java 11 pour le code principal, et Gradle affiche soudainement une erreur de compatibilité ? Cela vous dit quelque chose ? C'est l'un des problèmes les plus courants lors de la configuration de projets multi-modules. Surtout lorsque vous utilisez build.gradle.kts (Kotlin DSL) et que vous essayez de faire cohabiter compileJava avec compileKotlin. Dans cet article, nous allons voir comment définir correctement la compatibilité de la cible JVM pour Java 11 et Kotlin 1.8, afin que votre projet se compile sans erreur. Et oui, nous le ferons en français, avec humour et sans théorie ennuyeuse.

\n\n

Si vous venez de Stack Overflow, vous savez que la question originale a recueilli des milliers de vues. Nous l'adaptons ici dans un format éducatif pour que vous ne vous contentiez pas de copier la réponse, mais que vous compreniez pourquoi l'erreur se produit et comment l'éviter à l'avenir.

\n\n

Le problème : quand Java et Kotlin parlent des langues différentes

\n\n

Imaginez que Java 11 est un professeur strict qui exige que tout soit conforme à la norme. Et Kotlin 1.8 est son collègue créatif qui veut utiliser les nouvelles fonctionnalités, mais oublie d'en informer le professeur. Résultat : un conflit.

\n\n

Dans Gradle, chaque tâche de compilation (compileJava, compileKotlin) a sa propre cible JVM — la version du bytecode dans laquelle le code est compilé. Si elles ne correspondent pas, vous obtiendrez une erreur comme celle-ci :

\n\n
Error: Module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.8.0, expected version is 1.6.0.\n
\n\n

Ou, pire encore, une baisse silencieuse des performances due à une incompatibilité du bytecode.

\n\n

Pourquoi cela se produit-il spécifiquement dans build.gradle.kts ?

\n\n

Le Kotlin DSL (fichiers .gradle.kts) est un outil puissant, mais il nécessite une spécification explicite des paramètres. Contrairement au Groovy DSL où certains réglages sont « repris » automatiquement, dans le Kotlin DSL, vous devez être précis. Cela concerne particulièrement la cible JVM.

\n\n

L'erreur typique : vous définissez java.targetCompatibility = JavaVersion.VERSION_11, mais vous oubliez de faire de même pour Kotlin. Ou inversement — vous configurez compileKotlin, tandis que compileJava reste sur Java 8.

\n\n

La solution correcte : une cible JVM unique pour Java et Kotlin

\n\n

Pour éviter les erreurs, vous devez définir explicitement la cible JVM pour les deux tâches. Voici comment faire dans build.gradle.kts :

\n\n

Étape 1. Configuration de Java (compileJava)

\n\n

Ajoutez dans le bloc java {} ou dans tasks.withType<JavaCompile>() :

\n\n
java {\n    sourceCompatibility = JavaVersion.VERSION_11\n    targetCompatibility = JavaVersion.VERSION_11\n}\n\ntasks.withType<JavaCompile>() {\n    options.encoding = "UTF-8"\n    options.compilerArgs.add("-parameters")\n}\n
\n\n

Notez que sourceCompatibility et targetCompatibility doivent être identiques. Si vous écrivez du code en Java 11, le bytecode doit également être Java 11.

\n\n

Étape 2. Configuration de Kotlin (compileKotlin)

\n\n

Maintenant, le plus important — définir la cible JVM pour Kotlin. Cela se fait via le bloc kotlin {} ou via tasks.withType<KotlinCompile>() :

\n\n
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile\n\ntasks.withType<KotlinCompile>() {\n    kotlinOptions {\n        jvmTarget = "11"  // Attention : c'est une chaîne, pas un JavaVersion !\n        apiVersion = "1.8"\n        languageVersion = "1.8"\n    }\n}\n
\n\n

Pourquoi jvmTarget est-il une chaîne ? Parce que Kotlin attend une représentation textuelle de la version (par exemple, "1.8", "11", "17"). Si vous essayez de passer JavaVersion.VERSION_11, le compilateur générera une erreur.

\n\n

Exemple complet de build.gr

Blogs

Book Recommendations