ما هي Java؟ JDK وJRE وJVM
ما هي Java؟ JDK وJRE وJVM
تُعدّ Java واحدة من أكثر لغات البرمجة استخدامًا في العالم. إنّها تعمل في كل مكان — من هواتف Android إلى خوادم المؤسسات الخلفية، ومن الأجهزة المُدمجة إلى منصّات الحوسبة السحابية. قبل أن تكتب سطرًا واحدًا من الكود، من المفيد أن تفهم لماذا صُمِّمت Java بهذه الطريقة وكيف تعمل مكوّناتها الثلاثة الرئيسية — JDK وJRE وJVM — معًا.
لمحة تاريخية موجزة
أنشأ Java جيمس غوسلينغ وفريقه في شركة Sun Microsystems عام 1995. كان الدافع الأصلي عمليًا بشكل لافت: كانت الأجهزة الإلكترونية الاستهلاكية — كأجهزة فك تشفير التلفزيون والحواسيب الكفّية — تعمل على بنيات CPU متعددة ومختلفة. كتابة برامج منفصلة لكل رقاقة كانت مكلفة للغاية. احتاج الفريق إلى لغة تعمل برامجها المُجمَّعة على أي جهاز دون إعادة تجميع.
أطلقت Sun على Java شعارها الشهير "اكتب مرة، شغّل في كل مكان" (Write Once, Run Anywhere — WORA). هذا الوعد لا يزال في صميم Java حتى اليوم، يحافظ عليه Oracle ومجتمع OpenJDK.
اكتب مرة، شغّل في كل مكان — كيف يعمل ذلك؟
معظم اللغات المُجمَّعة (كـ C وC++) تُترجم كودك المصدري مباشرة إلى كود آلة — تعليمات ثنائية لا تفهمها سوى عائلة CPU محددة. هذا يعني أنك يجب أن تُعيد التجميع لكل منصة تستهدفها.
تتّبع Java نهجًا مختلفًا. المُجمِّع لا ينتج كود آلة. بدلًا من ذلك يُنتج بايت كود — مجموعة تعليمات مضغوطة محايدة تجاه المنصة، مُخزَّنة في ملفات .class. البايت كود غير قابل للتنفيذ على أي CPU حقيقية. إنّه نوع من الوصفة التي يُفسِّرها وينفّذها برنامج خاص — الجهاز الافتراضي لـ Java (JVM) — أثناء التشغيل.
لأن JVM متاح على Windows وmacOS وLinux ومئات المنصّات الأخرى، فإن نفس ملف .class يعمل دون تغيير في كل مكان:
يقرأ مُجمِّع javac ملف .java المصدري ويكتب ملف .class. يُحمِّل مُشغِّل java ملف .class إلى JVM وينفّذه. لن تتعامل مع كود الآلة أبدًا بنفسك.
الطبقات الثلاث: JVM وJRE وJDK
هذه الاختصارات الثلاثة تُربك كل مبتدئ تقريبًا. فكّر فيها على أنّها دوائر متداخلة — كل واحدة تحتوي على ما قبلها.
1 — JVM: الجهاز الافتراضي لـ Java
الـ JVM هو المحرّك الذي ينفّذ البايت كود. وهو مسؤول عن:
- تحميل ملفات
.classعبر ClassLoader. - التحقّق من البايت كود للتأكد من سلامته (عدم الوصول غير المشروع للذاكرة).
- تنفيذ التعليمات — إما بتفسيرها أو بتجميعها إلى كود أصلي (JIT).
- إدارة الذاكرة عبر جمع القمامة — تحرير الكائنات التي لم تعد بحاجة إليها تلقائيًا.
الـ JVM بحدّ ذاته محدَّد بالمنصة (هناك ملف JVM ثنائي منفصل لـ Windows وLinux وmacOS)، لكن البايت كود الذي يشغّله عالمي.
2 — JRE: بيئة تشغيل Java
الـ JRE هو JVM مُضاف إليه مكتبة الفئات القياسية — آلاف الفئات المُدمجة المُرفقة مع Java (java.lang وjava.util وjava.io وغيرها). إذا احتاج شخص فقط إلى تشغيل تطبيق Java (لا بناؤه)، يُنصَّب JRE.
jlink لتجميع وقت تشغيل أدنى داخل تطبيقك إذا لزم الأمر. عمليًا، يُنصِّب المطوّرون دائمًا JDK.
3 — JDK: مجموعة تطوير Java
الـ JDK هو كل ما في JRE مُضافًا إليه أدوات التطوير:
javac— المُجمِّع الذي يحوّل الكود المصدري.javaإلى بايت كود.class.java— المُشغِّل الذي يبدأ JVM.javadoc— يولّد توثيقًا HTML من تعليقات مُنسَّقة بطريقة خاصة.jar— يُحزِّم ملفات.classفي أرشيف واحد.jshell— بيئة REPL تفاعلية للتجريب مع مقاطع Java.- مُصحِّح أخطاء، ومُحلِّل أداء، وأدوات أخرى كثيرة.
بصفتك مطوّرًا، تُنصِّب JDK دائمًا. المستخدمون النهائيون الذين يُشغِّلون تطبيقك فحسب كانوا يحتاجون سابقًا إلى JRE فقط، لكن كما ذكرنا، التوزيعات الحديثة تُدمج JRE داخل كل JDK.
تصوير العلاقة
لماذا يهمّك هذا بصفتك مطوّرًا
فهم هذه الطبقات الثلاث يُوضِّح أشياء ستواجهها باستمرار:
- حين يقول زميل "تأكّد من وجود إصدار Java الصحيح في PATH"، يقصد مجلّد
bin/في JDK حيث يوجدjavacوjava. - حين تقول صورة Docker
FROM eclipse-temurin:17-jre، فهي تحتوي على JRE فقط — كافٍ لتشغيل تطبيق مُجمَّع لكن ليس لبنائه. - حين يُسطِّر IDE import مفقودًا، مكتبة فئات JRE هي التي تُوفِّر تلك الأنواع.
- حين يُلقي برنامج خطأ
OutOfMemoryError، جامع القمامة في JVM هو الذي نفد من مساحة الكومة.
UnsupportedClassVersionError عند الإقلاع. تأكّد دائمًا من أن إصدار تجميعك (علامة --release) يتطابق مع إصدار JVM في الإنتاج.
الخلاصة
تحقّق Java مبدأ الكتابة مرة والتشغيل في كل مكان بتجميع الكود المصدري إلى بايت كود محايد تجاه المنصة، تُنفِّذه JVM على أي نظام تشغيل مدعوم. تُجمِّع JRE الـ JVM مع المكتبة القياسية. أما JDK فيُضيف أدوات المطوّر — وفي مقدّمتها javac — فوق JRE. في الدرس التالي ستُنصِّب JDK وتكتب أولّ برنامج Java لك وتُجمِّعه وتُشغِّله.