Rencontre avec un fantôme : qu'est-ce que "unrecognized Attribute name MODULE" ?
\nAvez-vous déjà vu une erreur qui sent le mystère ? Imaginez : vous codez en Kotlin moderne, tout vole, Gradle ronronne, et soudain — bam ! — dans les logs apparaît quelque chose comme :
\nunrecognized Attribute name MODULE (class com.sun.tools.javac.util.SharedNameTable$NameImpl)\nVous cherchez sur Google, vous trouvez Stack Overflow avec des milliers de vues, et vous comprenez : ce n'est pas juste un bug. C'est une erreur de compatibilité entre les mondes. Entre Java et Kotlin. Entre l'ancien système de construction et le nouveau monde modulaire.
\nDans cet article, nous ne donnons pas seulement une solution. Nous allons regarder sous le capot du compilateur Java, analyser ce qu'est SharedNameTable, pourquoi la JVM se plaint du mot MODULE, et comment cela est lié à votre projet Kotlin. Spoiler : ce n'est pas Kotlin le coupable, mais l'ancien Gradle et Java 9+.
En bref : comment corriger (pour les impatients)
\nSi vous devez réparer la compilation de toute urgence — voici trois méthodes qui fonctionnent. Choisissez selon votre situation :
\n- \n
- Méthode 1 (recommandée) : Mettez à jour Gradle vers la version 7.0+ et le Plugin Gradle Kotlin vers 1.5+. Cela résoudra le problème définitivement. \n
- Méthode 2 (solution rapide) : Spécifiez explicitement la cible JVM dans
build.gradle.kts: \n
kotlin {\n jvmToolchain(11) // ou 8 si vous voulez une ancienne compatibilité\n}\n- \n
- Méthode 3 (solution de contournement) : Ajoutez un indicateur au compilateur : \n
tasks.withType<KotlinCompile> {\n kotlinOptions {\n jvmTarget = "1.8"\n }\n}\nMais si vous voulez comprendre pourquoi cela fonctionne — lisez la suite. Nous allons plonger dans les profondeurs du compilateur Java.
\n\nSous le capot : qu'est-ce que com.sun.tools.javac.util.SharedNameTable$NameImpl ?
\nDécortiquons cette ligne effrayante morceau par morceau. Ce n'est pas juste un ensemble de mots aléatoires — c'est une référence à une classe spécifique à l'intérieur du Java Development Kit (JDK).
\n- \n
com.sun.tools.javac— le paquet du compilateur Java interne (javac). Oui, celui qui transforme le.javaen.class. \n util.SharedNameTable— une classe utilitaire qui stocke les noms (variables, méthodes, classes) dans un pool de chaînes pour l'optimisation. C'est un cache pour éviter de créer un million de chaînes identiques. \n $NameImpl— une classe interne représentant un nom spécifique. Lorsque le compilateur rencontre le motmodule, il crée un objetNameImpl. \n
Et maintenant, le plus intéressant : l'erreur se produit lorsque javac tombe sur l'attribut MODULE dans un fichier class, mais ne sait pas quoi en faire. Cela arrive si vous utilisez un ancien compilateur (< Java 9) ou, à l'inverse, un nouveau compilateur mais un ancien format de fichier class.
\n\nPourquoi MODULE est-il un mot spécial ?
\nÀ partir de Java 9, le langage a introduit le système de modules (Project Jigsaw). Le mot-clé module est devenu réservé. Dans les fichiers class, de nouveaux attributs sont apparus : Module, ModulePackages, ModuleMainClass, etc.
Lorsque le compilateur Kotlin génère du bytecode, il peut accidentellement (ou intentionnellement) ajouter cet attribut si votre cible JVM est définie sur 9+. Et l'ancien Gradle ou Maven, utilisant une version obsolète de javac, ne comprend pas ces attributs. D'où l'erreur.
\n\nExemple concret : Kotlin + Gradle + Java 11
\nImaginez un simple projet Kotlin avec Gradle. Voici le fichier build.gradle.kts :
plugins {\n kotlin("jvm") version