اسم السمة غير المعترف به MODULE في Kotlin: تحليل الخطأ

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

لقاء مع الشبح: ما هو "unrecognized Attribute name MODULE"؟

\n

هل سبق لك أن رأيت خطأً ينبعث منه الغموض؟ تخيل: أنت تكتب بلغة Kotlin الحديثة، كل شيء يعمل بسلاسة، وGradle يدندن، وفجأة - بام! - يظهر في السجلات شيء مثل:

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

تبحث في Google، تجد Stack Overflow بآلاف المشاهدات، وتفهم: هذا ليس مجرد خطأ. إنه خطأ توافق بين العوالم. بين Java و Kotlin. بين نظام البناء القديم والعالم المعياري الجديد.

\n

في هذه المقالة، لن نقدم الحل فقط. سننظر تحت غطاء مترجم Java، ونحلل ما هو SharedNameTable، ولماذا JVM يعترض على كلمة MODULE، وكيف يرتبط ذلك بمشروع Kotlin الخاص بك. تنبيه: المذنب ليس Kotlin، بل Gradle القديم وJava 9+.

\n\n

باختصار: كيفية الإصلاح (لغير الصبورين)

\n

إذا كنت بحاجة ماسة لإصلاح البناء - إليك ثلاث طرق عملية. اختر حسب حالتك:

\n
    \n
  • الطريقة 1 (موصى بها): قم بتحديث Gradle إلى الإصدار 7.0+ و إضافة Kotlin Gradle إلى 1.5+. سيحل هذا المشكلة نهائياً.
  • \n
  • الطريقة 2 (حل سريع): حدد بوضوح هدف JVM في build.gradle.kts:
  • \n
\n
kotlin {\n    jvmToolchain(11) // أو 8 إذا كنت تريد التوافق القديم\n}
\n
    \n
  • الطريقة 3 (حل مؤقت): أضف علامة للمترجم:
  • \n
\n
tasks.withType<KotlinCompile> {\n    kotlinOptions {\n        jvmTarget = "1.8"\n    }\n}
\n

ولكن إذا كنت تريد فهم لماذا يعمل هذا - تابع القراءة. سنغوص في أعماق مترجم Java.

\n\n

تحت الغطاء: ما هو com.sun.tools.javac.util.SharedNameTable$NameImpl؟

\n

دعنا نحلل هذا السطر المخيف جزءاً جزءاً. إنها ليست مجرد مجموعة عشوائية من الكلمات - إنها إشارة إلى فئة محددة داخل مجموعة تطوير Java (JDK).

\n
    \n
  • com.sun.tools.javac - حزمة مترجم Java الداخلي (javac). نعم، ذلك الذي يحول .java إلى .class.
  • \n
  • util.SharedNameTable - فئة خدمية تخزن الأسماء (المتغيرات، الدوال، الفئات) في مجموعة سلاسل للتحسين. إنها ذاكرة تخزين مؤقت لتجنب إنشاء ملايين السلاسل المتطابقة.
  • \n
  • $NameImpl - فئة داخلية تمثل اسماً محدداً. عندما يواجه المترجم كلمة module، يقوم بإنشاء كائن NameImpl.
  • \n
\n

والآن الجزء الأكثر إثارة للاهتمام: يحدث الخطأ عندما يصادف javac سمة MODULE في ملف class، لكنه لا يعرف ماذا يفعل بها. يحدث هذا إذا كنت تستخدم مترجماً قديماً (< Java 9) أو، على العكس، مترجماً جديداً ولكن بصيغة ملفات class قديمة.

\n\n

لماذا MODULE كلمة خاصة؟

\n

ابتداءً من Java 9، ظهر في اللغة نظام الوحدات (Project Jigsaw). أصبحت الكلمة المحجوزة module محجوزة. ظهرت في ملفات class سمات جديدة مثل Module و ModulePackages و ModuleMainClass وغيرها.

\n

عندما يقوم مترجم Kotlin بتوليد البايت كود، قد يضيف هذه السمة بشكل عشوائي (أو متعمد) إذا كان هدف JVM الخاص بك مضبوطاً على 9+. أما Gradle القديم أو Maven، باستخدام إصدار قديم من javac، فلا يفهم هذه السمات. ومن هنا يأتي الخطأ.

\n\n

مثال واقعي: Kotlin + Gradle + Java 11

\n

تخيل مشروع Kotlin بسيطاً على Gradle. إليك ملف build.gradle.kts:

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

المدونات

توصيات الكتب