JavaRush /جاوا بلاگ /Random-UR /JVM میں کلاسز کیسے بھری جاتی ہیں۔
Aleksandr Zimin
سطح
Санкт-Петербург

JVM میں کلاسز کیسے بھری جاتی ہیں۔

گروپ میں شائع ہوا۔
پروگرامر کے کام کا سب سے مشکل حصہ مکمل ہونے کے بعد اور "Hello World 2.0" ایپلی کیشن لکھے جانے کے بعد، صرف ڈسٹری بیوشن کٹ کو اسمبل کرنا اور اسے کسٹمر، یا کم از کم ٹیسٹنگ سروس میں منتقل کرنا باقی ہے۔ تقسیم میں، سب کچھ ویسا ہی ہے جیسا کہ ہونا چاہیے، اور جب ہم اپنا پروگرام شروع کرتے ہیں، تو جاوا ورچوئل مشین منظر پر آتی ہے۔ یہ کوئی راز نہیں ہے کہ ورچوئل مشین کلاس فائلوں میں پیش کردہ کمانڈز کو بائی کوڈ کی شکل میں پڑھتی ہے اور ان کا ترجمہ پروسیسر کو ہدایات کے طور پر کرتی ہے۔ میں ورچوئل مشین میں بائیک کوڈ حاصل کرنے کی اسکیم کے بارے میں تھوڑا سا سمجھنے کی تجویز کرتا ہوں۔

کلاس لوڈر

اس کا استعمال JVM کو مرتب کردہ بائٹ کوڈ کی فراہمی کے لیے کیا جاتا ہے، جو عام طور پر ایکسٹینشن کے ساتھ فائلوں میں محفوظ ہوتا ہے .class، لیکن دوسرے ذرائع سے بھی حاصل کیا جا سکتا ہے، مثال کے طور پر، نیٹ ورک پر ڈاؤن لوڈ کیا گیا یا ایپلیکیشن کے ذریعے ہی تیار کیا گیا۔ JVM - 1 میں کلاسیں کیسے لوڈ کی جاتی ہیں۔جاوا SE تفصیلات کے مطابق، JVM میں کوڈ چلانے کے لیے، آپ کو تین مراحل مکمل کرنے کی ضرورت ہے:
  • وسائل سے بائٹ کوڈ لوڈ کرنا اور کلاس کی مثال بناناClass

    اس میں پہلے لوڈ ہونے والوں میں سے درخواست کردہ کلاس کو تلاش کرنا، لوڈنگ کے لیے بائیک کوڈ حاصل کرنا اور اس کی درستگی کی جانچ کرنا، کلاس کی ایک مثال بنانا Class(رن ٹائم پر اس کے ساتھ کام کرنے کے لیے)، اور پیرنٹ کلاسز کو لوڈ کرنا شامل ہے۔ اگر پیرنٹ کلاسز اور انٹرفیس کو لوڈ نہیں کیا گیا ہے، تو زیر بحث کلاس کو لوڈ نہیں کیا گیا ہے۔

  • بائنڈنگ (یا لنک کرنا)

    تفصیلات کے مطابق، اس مرحلے کو مزید تین مراحل میں تقسیم کیا گیا ہے:

    • توثیق ، موصول ہونے والے بائیک کوڈ کی درستگی کی جانچ کی جاتی ہے۔
    • تیاری ، جامد فیلڈز کے لیے RAM کو مختص کرنا اور انہیں پہلے سے طے شدہ اقدار کے ساتھ شروع کرنا (اس صورت میں، واضح ابتداء، اگر کوئی ہے، پہلے سے ہی ابتدائی مرحلے پر ہوتی ہے)۔
    • ریزولوشن ، اقسام، شعبوں اور طریقوں کے علامتی روابط کا حل۔
  • موصولہ آبجیکٹ کو شروع کرنا

    یہاں، پچھلے پیراگراف کے برعکس، سب کچھ واضح نظر آتا ہے کہ کیا ہونا چاہیے۔ یقیناً یہ سمجھنا دلچسپ ہوگا کہ یہ کیسے ہوتا ہے۔

یہ تمام اقدامات درج ذیل تقاضوں کے ساتھ ترتیب وار انجام دیئے جاتے ہیں۔
  • منسلک ہونے سے پہلے کلاس کو مکمل طور پر لوڈ کیا جانا چاہیے۔
  • ایک کلاس کو شروع کرنے سے پہلے اس کی مکمل جانچ اور تیاری ہونی چاہیے۔
  • لنک ریزولوشن کی خرابیاں پروگرام کے عمل کے دوران ہوتی ہیں، چاہے ان کا پتہ لنکنگ کے مرحلے پر ہی کیوں نہ ہو۔
جیسا کہ آپ جانتے ہیں، جاوا کلاسز کی سست (یا سست) لوڈنگ کو لاگو کرتا ہے۔ اس کا مطلب یہ ہے کہ بھری ہوئی کلاس کے ریفرنس فیلڈز کی کلاسز کی لوڈنگ اس وقت تک نہیں کی جائے گی جب تک کہ ایپلی کیشن کو ان کے لیے واضح حوالہ کا سامنا نہ ہو۔ دوسرے الفاظ میں، علامتی روابط کو حل کرنا اختیاری ہے اور پہلے سے طے شدہ نہیں ہوتا۔ تاہم، JVM کا نفاذ توانائی بخش کلاس لوڈنگ کا بھی استعمال کر سکتا ہے، یعنی تمام علامتی روابط کو فوری طور پر مدنظر رکھنا چاہیے۔ اس نکتے کے لیے آخری شرط لاگو ہوتی ہے۔ یہ بات بھی قابل غور ہے کہ علامتی روابط کی ریزولوشن کلاس لوڈنگ کے کسی بھی مرحلے سے منسلک نہیں ہے۔ عام طور پر، ان مراحل میں سے ہر ایک اچھا مطالعہ کرتا ہے؛ آئیے پہلے کو جاننے کی کوشش کریں، یعنی بائی کوڈ لوڈ کرنا۔

جاوا لوڈرز کی اقسام

جاوا میں تین معیاری لوڈرز ہیں، جن میں سے ہر ایک مخصوص جگہ سے کلاس لوڈ کرتا ہے۔
  1. بوٹسٹریپ ایک بنیادی لوڈر ہے، جسے Primordial ClassLoader بھی کہا جاتا ہے۔

    rt.jar آرکائیو سے معیاری JDK کلاسز لوڈ کرتا ہے۔

  2. ایکسٹینشن کلاس لوڈر - ایکسٹینشن لوڈر۔

    ایکسٹینشن کلاسز کو لوڈ کرتا ہے، جو ڈیفالٹ کے طور پر jre/lib/ext ڈائرکٹری میں موجود ہیں، لیکن java.ext.dirs سسٹم پراپرٹی کے ذریعے سیٹ کی جا سکتی ہیں۔

  3. سسٹم کلاس لوڈر - سسٹم لوڈر۔

    CLASSPATH ماحولیاتی متغیر میں بیان کردہ ایپلیکیشن کلاسز کو لوڈ کرتا ہے۔

جاوا کلاس لوڈرز کے درجہ بندی کا استعمال کرتا ہے، جہاں جڑ، یقینا، بنیادی ہے. اگلا ایکسٹینشن لوڈر آتا ہے، اور پھر سسٹم لوڈر۔ قدرتی طور پر، ہر لوڈر والدین کے لیے ایک پوائنٹر اسٹور کرتا ہے تاکہ اس صورت میں کہ وہ خود ایسا کرنے سے قاصر ہو اسے لوڈنگ کی ذمہ داری سونپنے کے قابل ہو۔

خلاصہ کلاس کلاس لوڈر

ہر لوڈر، بیس ون کو چھوڑ کر، تجریدی کلاس کی اولاد ہے java.lang.ClassLoader۔ مثال کے طور پر، ایکسٹینشن لوڈر کا نفاذ کلاس ہے sun.misc.Launcher$ExtClassLoader، اور سسٹم لوڈر ہے sun.misc.Launcher$AppClassLoader۔ بیس لوڈر مقامی ہے اور اس کا نفاذ JVM میں شامل ہے۔ کوئی بھی کلاس جو توسیع کرتی ہے وہ java.lang.ClassLoaderبلیک جیک اور انہی کلاسوں کے ساتھ کلاس لوڈ کرنے کا اپنا طریقہ فراہم کر سکتی ہے۔ ایسا کرنے کے لئے، متعلقہ طریقوں کو دوبارہ بیان کرنا ضروری ہے، جس میں اس وقت میں صرف سطحی طور پر غور کر سکتا ہوں، کیونکہ میں اس مسئلے کو تفصیل سے نہیں سمجھا۔ وہ یہاں ہیں:
package java.lang;
public abstract class ClassLoader {
    public Class<?> loadClass(String name);
    protected Class<?> loadClass(String name, boolean resolve);
    protected final Class<?> findLoadedClass(String name);
    public final ClassLoader getParent();
    protected Class<?> findClass(String name);
    protected final void resolveClass(Class<?> c);
}
loadClass(String name)چند عوامی طریقوں میں سے ایک، جو کلاسوں کو لوڈ کرنے کا انٹری پوائنٹ ہے۔ اس کا نفاذ ایک اور محفوظ طریقہ کو کال کرنے پر ابلتا ہے loadClass(String name, boolean resolve)، جسے اوور رائڈ کرنے کی ضرورت ہے۔ اگر آپ اس محفوظ طریقے کے Javadoc کو دیکھیں تو آپ کچھ اس طرح سمجھ سکتے ہیں: دو پیرامیٹرز بطور ان پٹ فراہم کیے گئے ہیں۔ ایک کلاس کا بائنری نام (یا مکمل طور پر اہل کلاس کا نام) جسے لوڈ کرنے کی ضرورت ہے۔ کلاس کا نام تمام پیکجوں کی فہرست کے ساتھ بیان کیا گیا ہے۔ دوسرا پیرامیٹر ایک جھنڈا ہے جو اس بات کا تعین کرتا ہے کہ آیا علامتی لنک ریزولوشن کی ضرورت ہے۔ پہلے سے طے شدہ طور پر یہ غلط ہے ، جس کا مطلب ہے کہ سست کلاس لوڈنگ استعمال کی جاتی ہے۔ مزید، دستاویزات کے مطابق، طریقہ کار کے پہلے سے طے شدہ نفاذ میں، ایک کال کی جاتی ہے findLoadedClass(String name)، جو چیک کرتی ہے کہ آیا کلاس پہلے ہی لوڈ ہو چکی ہے اور، اگر ایسا ہے تو، اس کلاس کا حوالہ واپس کرتا ہے۔ بصورت دیگر، پیرنٹ لوڈر کا کلاس لوڈ کرنے کا طریقہ کہا جائے گا۔ اگر لوڈرز میں سے کوئی بھی بھری ہوئی کلاس نہیں ڈھونڈ سکتا ہے، تو ان میں سے ہر ایک، الٹ ترتیب میں، اس کلاس کو تلاش کرنے اور لوڈ کرنے کی کوشش کرے گا، کو اوور رائیڈ کرتے ہوئے findClass(String name)۔ اس پر مزید تفصیل سے باب "کلاس لوڈنگ اسکیم" میں بحث کی جائے گی۔ اور آخر میں، آخری لیکن کم از کم، کلاس کے لوڈ ہونے کے بعد، ریزول فلیگ پر منحصر ہے ، یہ فیصلہ کیا جائے گا کہ آیا کلاسز کو علامتی لنکس کے ذریعے لوڈ کرنا ہے۔ ایک واضح مثال یہ ہے کہ ریزولوشن سٹیج کو کلاس لوڈنگ سٹیج کے دوران بلایا جا سکتا ہے۔ اس کے مطابق، کلاس کو بڑھا کر ClassLoaderاور اس کے طریقوں کو اوور رائیڈ کر کے، کسٹم لوڈر ورچوئل مشین کو بائیک کوڈ فراہم کرنے کے لیے اپنی منطق کو نافذ کر سکتا ہے۔ جاوا "موجودہ" کلاس لوڈر کے تصور کی بھی حمایت کرتا ہے۔ موجودہ لوڈر وہ ہے جس نے فی الحال ایگزیکیوٹنگ کلاس کو لوڈ کیا ہے۔ ہر کلاس کو معلوم ہوتا ہے کہ اسے کس لوڈر کے ساتھ لوڈ کیا گیا تھا، اور آپ اسے کال کر کے یہ معلومات حاصل کر سکتے ہیں String.class.getClassLoader()۔ تمام ایپلیکیشن کلاسز کے لیے، "موجودہ" لوڈر عام طور پر سسٹم ون ہوتا ہے۔

کلاس لوڈنگ کے تین اصول

  • وفد

    کلاس کو لوڈ کرنے کی درخواست پیرنٹ لوڈر کو بھیجی جاتی ہے، اور کلاس کو خود لوڈ کرنے کی کوشش صرف اس صورت میں کی جاتی ہے جب پیرنٹ لوڈر کلاس کو تلاش کرنے اور لوڈ کرنے میں ناکام ہو۔ یہ نقطہ نظر آپ کو لوڈر کے ساتھ کلاسز لوڈ کرنے کی اجازت دیتا ہے جو کہ بیس ون کے جتنا ممکن ہو قریب ہو۔ اس سے کلاس کی زیادہ سے زیادہ مرئیت حاصل ہوتی ہے۔ ہر لوڈر ان کلاسوں کا ریکارڈ رکھتا ہے جو اس کے ذریعہ لوڈ کی گئی تھیں، انہیں اپنے کیشے میں رکھ کر۔ ان کلاسوں کے سیٹ کو دائرہ کار کہا جاتا ہے۔

  • مرئیت

    لوڈر صرف "اپنی" کلاسز اور "والدین" کی کلاسز کو دیکھتا ہے اور اسے ان کلاسوں کے بارے میں کوئی اندازہ نہیں ہے جو اس کے "بچے" نے لوڈ کیے تھے۔

  • انفرادیت

    کلاس صرف ایک بار لوڈ کی جا سکتی ہے۔ وفد کا طریقہ کار اس بات کو یقینی بناتا ہے کہ لوڈر جو کلاس لوڈنگ شروع کرتا ہے اس کلاس کو اوورلوڈ نہ کرے جو پہلے JVM میں لوڈ کیا گیا تھا۔

اس طرح، اپنا بوٹ لوڈر لکھتے وقت، ایک ڈویلپر کو ان تین اصولوں سے رہنمائی کرنی چاہیے۔

کلاس لوڈنگ اسکیم

جب کلاس لوڈ کرنے کی کال آتی ہے، تو اس کلاس کو موجودہ لوڈر کی پہلے سے بھری ہوئی کلاسوں کے کیشے میں تلاش کیا جاتا ہے۔ اگر مطلوبہ کلاس کو پہلے لوڈ نہیں کیا گیا ہے، تو ڈیلیگیشن کا اصول پیرنٹ لوڈر کو کنٹرول منتقل کرتا ہے، جو درجہ بندی میں ایک درجے اوپر واقع ہے۔ پیرنٹ لوڈر بھی اپنے کیشے میں مطلوبہ کلاس تلاش کرنے کی کوشش کرتا ہے۔ اگر کوئی کلاس پہلے ہی لوڈ ہو چکی ہے اور لوڈر کو اس کا مقام معلوم ہے تو Classاس کلاس کا ایک آبجیکٹ واپس کر دیا جائے گا۔ اگر نہیں، تو تلاش جاری رہے گی جب تک کہ یہ بیس بوٹ لوڈر تک نہ پہنچ جائے۔ اگر بیس لوڈر کے پاس مطلوبہ کلاس کے بارے میں معلومات نہیں ہیں (یعنی اسے ابھی تک لوڈ نہیں کیا گیا ہے)، اس کلاس کے بائیک کوڈ کو ان کلاسز کے مقام پر تلاش کیا جائے گا جس کے بارے میں دیا گیا لوڈر جانتا ہے، اور اگر کلاس نہیں کر سکتی ہے۔ لوڈ کیا جائے گا، کنٹرول چائلڈ لوڈر پر واپس آ جائے گا، جو اس کے جاننے والے ذرائع سے لوڈ کرنے کی کوشش کرے گا۔ جیسا کہ اوپر بتایا گیا ہے، بیس لوڈر کے لیے کلاسز کا مقام rt.jar لائبریری ہے، ایکسٹینشن لوڈر کے لیے - jre/lib/ext ایکسٹینشن والی ڈائریکٹری، سسٹم ون کے لیے - CLASSPATH، صارف کے لیے یہ کچھ مختلف ہو سکتا ہے۔ . اس طرح، لوڈنگ کلاسز کی پیشرفت مخالف سمت میں جاتی ہے - روٹ لوڈر سے کرنٹ تک۔ جب کلاس کا بائیک کوڈ مل جاتا ہے، کلاس کو JVM میں لوڈ کیا جاتا ہے اور قسم کی ایک مثال حاصل کی جاتی ہے Class۔ جیسا کہ آپ آسانی سے دیکھ سکتے ہیں، بیان کردہ لوڈنگ اسکیم مذکورہ طریقہ کے نفاذ سے ملتی جلتی ہے loadClass(String name)۔ ذیل میں آپ اس خاکہ کو خاکہ میں دیکھ سکتے ہیں۔
JVM - 2 میں کلاسیں کیسے لوڈ کی جاتی ہیں۔

ایک نتیجہ کے طور پر

زبان سیکھنے کے پہلے مراحل میں، یہ سمجھنے کی کوئی خاص ضرورت نہیں ہے کہ جاوا میں کلاسز کیسے بھری جاتی ہیں، لیکن ان بنیادی اصولوں کو جاننے سے آپ کو یا جیسے غلطیوں کا سامنا کرنے پر مایوسی سے بچنے میں مدد ملے ClassNotFoundExceptionگی NoClassDefFoundError۔ ٹھیک ہے، یا کم از کم موٹے طور پر سمجھیں کہ مسئلہ کی جڑ کیا ہے۔ اس طرح، ایک استثناء ClassNotFoundExceptionاس وقت ہوتا ہے جب ایک کلاس کو پروگرام کے عمل کے دوران متحرک طور پر لوڈ کیا جاتا ہے، جب لوڈرز مطلوبہ کلاس کو یا تو کیشے میں یا کلاس کے راستے میں تلاش نہیں کرسکتے ہیں۔ لیکن غلطی NoClassDefFoundErrorزیادہ اہم ہے اور اس وقت ہوتی ہے جب تالیف کے دوران مطلوبہ کلاس دستیاب تھی، لیکن پروگرام کے عمل کے دوران نظر نہیں آتی تھی۔ ایسا ہو سکتا ہے اگر پروگرام اس لائبریری کو شامل کرنا بھول جائے جسے وہ استعمال کرتا ہے۔ ٹھیک ہے، اس آلے کی ساخت کے اصولوں کو سمجھنے کی حقیقت جو آپ اپنے کام میں استعمال کرتے ہیں (ضروری نہیں کہ اس کی گہرائیوں میں واضح اور تفصیلی ڈوبی ہو) اس میکانزم کے اندر ہونے والے عمل کی تفہیم میں کچھ واضح اضافہ کرتا ہے، جس میں ٹرن، اس ٹول کے پر اعتماد استعمال کی طرف جاتا ہے۔

ذرائع

جاوا میں کلاس لوڈر کیسے کام کرتا ہے مجموعی طور پر معلومات کی قابل رسائی پیشکش کے ساتھ ایک بہت ہی مفید ذریعہ ہے۔ لوڈنگ کلاسز، ClassLoader کافی لمبا مضمون ہے، لیکن اس بات پر زور دینے کے ساتھ کہ ان ہی کے ساتھ اپنا لوڈر لاگو کیسے کریں۔ ClassLoader: کلاسوں کی متحرک لوڈنگ بدقسمتی سے، یہ وسیلہ ابھی دستیاب نہیں ہے، لیکن وہاں مجھے کلاس لوڈنگ اسکیم کے ساتھ سب سے زیادہ قابل فہم خاکہ ملا، اس لیے میں اسے شامل کرنے کے علاوہ مدد نہیں کر سکتا۔ جاوا SE تفصیلات: باب 5. لوڈ کرنا، لنک کرنا، اور شروع کرنا
تبصرے
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION