Nom d'attribut non reconnu MODULE dans Kotlin : analyse de l'erreur

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

Rencontre avec un fantôme : qu'est-ce que "unrecognized Attribute name MODULE" ?

\n

Avez-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 :

\n
unrecognized Attribute name MODULE (class com.sun.tools.javac.util.SharedNameTable$NameImpl)
\n

Vous 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.

\n

Dans 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+.

\n\n

En bref : comment corriger (pour les impatients)

\n

Si 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
\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
\n
tasks.withType<KotlinCompile> {\n    kotlinOptions {\n        jvmTarget = "1.8"\n    }\n}
\n

Mais si vous voulez comprendre pourquoi cela fonctionne — lisez la suite. Nous allons plonger dans les profondeurs du compilateur Java.

\n\n

Sous le capot : qu'est-ce que com.sun.tools.javac.util.SharedNameTable$NameImpl ?

\n

Dé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 .java en .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 mot module, il crée un objet NameImpl.
  • \n
\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\n

Pourquoi 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.

\n

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\n

Exemple concret : Kotlin + Gradle + Java 11

\n

Imaginez un simple projet Kotlin avec Gradle. Voici le fichier build.gradle.kts :

\n
plugins {\n    kotlin("jvm") version                

Blogs

Book Recommendations