থ্রেডের প্রসঙ্গ বর্গ লোডার এবং সাধারণ শ্রেণি লোডারের মধ্যে পার্থক্য


242

কোনও থ্রেডের প্রসঙ্গ শ্রেনী লোডার এবং একটি সাধারণ বর্গ লোডার মধ্যে পার্থক্য কী?

তা হল, যদি Thread.currentThread().getContextClassLoader()এবং getClass().getClassLoader()বিভিন্ন শ্রেণীর লোডার অবজেক্টগুলি ফেরত দেয় তবে কোনটি ব্যবহৃত হবে?

উত্তর:


151

প্রতিটি ক্লাস অন্যান্য ক্লাস লোড করতে নিজস্ব শ্রেণি লোডার ব্যবহার করবে। সুতরাং যদি ClassA.classরেফারেন্সগুলি ClassB.classতখন ClassBশ্রেণীবদ্ধার ClassAবা তার পিতামাতার ক্লাসপথে থাকতে হবে ।

থ্রেড প্রসঙ্গে ক্লাসলোডার হ'ল বর্তমান থ্রেডের বর্তমান ক্লাসলোডার। একটি ক্লাস থেকে একটি অবজেক্ট তৈরি করা যেতে পারে ClassLoaderCএবং তারপরে মালিকানাধীন একটি থ্রেডে প্রেরণ করা যায় ClassLoaderD। এই ক্ষেত্রে অবজেক্টটি Thread.currentThread().getContextClassLoader()সরাসরি ব্যবহার করা দরকার যদি এটি নিজস্ব শ্রেণিবোর্ডারে উপলব্ধ না এমন সংস্থানগুলি লোড করতে চায়।


1
আপনি কেন বলছেন যে এটি ClassBঅবশ্যই ClassA'র লোডার'র ক্লাসপথে থাকতে হবে (বা ClassAএর লোডার বাবা-মা)? ClassAএর লোডারের পক্ষে ওভাররাইড করা কি সম্ভব নয় loadClass(), যেমন শ্রেণিপথে না ClassBথাকলেও এটি সফলভাবে লোড করতে পারে ClassB?
পেসারিয়ার

8
প্রকৃতপক্ষে, সমস্ত শ্রেণিবদ্ধদের ক্লাসপাথ নেই have যখন "ক্লাসবি ক্লাসএর শ্রেণিবদ্ধার শ্রেণিপথের উপরে থাকা দরকার" লেখা হয়েছিল, তখন আমি "ক্লাসবি'র শ্রেণিবোর্ডার দ্বারা ক্লাসবি লোডযোগ্য হওয়া দরকার" বোঝানো হয়েছিল। 90% সময় তাদের একই অর্থ। তবে আপনি যদি কোনও ইউআরএল ভিত্তিক ক্লাসলোডার ব্যবহার না করে থাকেন তবে কেবল দ্বিতীয় ক্ষেত্রেটিই সত্য।
ডেভিড রুসেল

" ClassA.classরেফারেন্স ClassB.class" বলার অর্থ কী ?
জামেশফিশার

1
যখন ক্লাসএ-এর ক্লাসবিয়ের জন্য একটি আমদানি বিবৃতি থাকে বা ক্লাসএতে এমন কোনও পদ্ধতি থাকে যেখানে ক্লাসবি টাইপের স্থানীয় ভেরিয়েবল থাকে। এটি ক্লাসবিটিকে লোড করার জন্য ট্রিগার করবে, যদি এটি ইতিমধ্যে লোড হয় না।
ডেভিড রুসেল

আমি মনে করি আমার সমস্যা এই বিষয়ের সাথে যুক্ত is আমার একাকীকরণ সম্পর্কে আপনি কী ভাবেন? আমি জানি যে এটা একটা ভালো প্যাটার্ন নয়, কিন্তু আমি কিভাবে এটা ঠিক করার অন্য কোন ধারণা আছে না: stackoverflow.com/questions/29238493/...
মার্সিন Erbel

109

এটি আসল প্রশ্নের উত্তর দেয় না, তবে যেহেতু প্রশ্নটি উচ্চ স্তরের এবং যে কোনও ContextClassLoaderপ্রশ্নের জন্য লিঙ্কযুক্ত , আমি প্রাসঙ্গিক শ্রেণীর লোডার কখন ব্যবহার করা উচিত সে সম্পর্কিত প্রশ্নের উত্তর দেওয়া গুরুত্বপূর্ণ বলে আমি মনে করি। সংক্ষিপ্ত উত্তর: প্রসঙ্গ বর্গ লোডার কখনও ব্যবহার করবেন না ! আপনি getClass().getClassLoader()যখন কোনও ClassLoaderপ্যারামিটার অনুপস্থিত এমন কোনও কল করতে হবে তখন সেট করুন ।

যখন একটি শ্রেণীর কোড অন্য ক্লাসটি লোড করতে বলে, সঠিক ক্লাস লোডারটি ব্যবহার করার জন্য কলার ক্লাস (যেমন, getClass().getClassLoader()) হিসাবে একই শ্রেণীর লোডার । এইভাবে জিনিসগুলি 99.9% সময়ের মতো কাজ করে কারণ আপনি যখন প্রথমবার নতুন ক্লাসের উদাহরণ তৈরি করেন, স্থির পদ্ধতিটি চালু করেন বা কোনও স্থির ক্ষেত্র অ্যাক্সেস করেন তখন JVM নিজেই এটি করে

আপনি যখন প্রতিবিম্বটি ব্যবহার করে কোনও ক্লাস তৈরি করতে চান (যেমন কোনও কনফিগারযোগ্য নামযুক্ত শ্রেণীর ডিজিটালাইজেশন বা লোড করার সময়), গ্রন্থাগারটি প্রতিবিম্বটি করে সেগুলি অ্যাপ্লিকেশনClassLoader থেকে প্যারামিটার হিসাবে সর্বদা কোন শ্রেণীর লোডারটি ব্যবহার করতে হবে সেই আবেদনটি জিজ্ঞাসা করা উচিত । অ্যাপ্লিকেশনটির (যা নির্মাণের প্রয়োজন এমন সমস্ত শ্রেণীর জানে) এটি পাস করা উচিত getClass().getClassLoader()

কোনও শ্রেণি লোডার পাওয়ার অন্য কোনও উপায় ভুল is যদি কোনও লাইব্রেরি হ্যাক ব্যবহার করে যেমন Thread.getContextClassLoader(), sun.misc.VM.latestUserDefinedLoader()বা sun.reflect.Reflection.getCallerClass()এটি এপিআই-এর অভাবজনিত একটি বাগ। মূলত, Thread.getContextClassLoader()কেবলমাত্র বিদ্যমান কারণ ObjectInputStreamএপিআই ডিজাইন করা যিনি ClassLoaderপ্যারামিটার হিসাবে গ্রহণ করতে ভুলে গিয়েছিলেন এবং এই ভুলটি আজও জাভা সম্প্রদায়কে ভুতুড়ে ফেলেছে।

এটি বলেছিল যে অনেকগুলি জেডিকে ক্লাস ব্যবহার করতে কিছু বর্গ লোডার অনুমান করতে কয়েকটি হ্যাকগুলির মধ্যে একটি ব্যবহার করে। কেউ কেউ ব্যবহার করেন ContextClassLoader(যা আপনি যখন ভাগ করা থ্রেড পুলে বিভিন্ন অ্যাপ্লিকেশন চালাবেন বা ব্যর্থ হয়ে যান বা ছেড়ে চলে যান ContextClassLoader null), কেউ কেউ স্ট্যাকটি হাঁটেন (যা ক্লাসের প্রত্যক্ষ কলার নিজেই লাইব্রেরি হয়ে গেলে ব্যর্থ হয়), কেউ সিস্টেম ক্লাস লোডার ব্যবহার করে (যা ঠিক আছে, যতক্ষণ না এটি কেবলমাত্র ক্লাস ব্যবহারের জন্য ডকুমেন্টেড থাকে CLASSPATH) বা বুটস্ট্র্যাপ শ্রেণীর লোডার এবং কেউ কেউ উপরের কৌশলগুলির একটি অপ্রত্যাশিত সংমিশ্রণ ব্যবহার করে (যা কেবল জিনিসগুলিকে আরও বিভ্রান্ত করে তোলে)। এর ফলে দাঁত কাঁদতে কাঁদতে এবং কাঁদতে পারে।

এই জাতীয় কোনও এপিআই ব্যবহার করার সময় প্রথমে ক্লাস লোডারকে প্যারামিটার হিসাবে গ্রহণ করে এমন পদ্ধতির একটি ওভারলোড অনুসন্ধান করার চেষ্টা করুন । যদি কোনও বুদ্ধিমান পদ্ধতি না থাকে, তবে ContextClassLoaderএপিআই কলের আগে সেট করার চেষ্টা করুন (এবং এটির পরে পুনরায় সেট করুন):

ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
try {
    Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
    // call some API that uses reflection without taking ClassLoader param
} finally {
    Thread.currentThread().setContextClassLoader(originalClassLoader);
}

5
হ্যাঁ, এই উত্তরটি আমি কারও কাছে জিজ্ঞাসা করে জিজ্ঞাসা করব।
মার্কো টপলনিক

6
এই উত্তরটি ক্লাস লোডার শ্রেণি লোড করার জন্য (তাদের প্রতিবিম্ব বা অনুরূপ মাধ্যমে তাত্ক্ষণিকভাবে ব্যবহার করার জন্য) উপর দৃষ্টি নিবদ্ধ করে, অন্য যে উদ্দেশ্যে এটি ব্যবহার করা হয় (এবং বাস্তবে, আমি একমাত্র উদ্দেশ্যে যা ব্যক্তিগতভাবে এটি ব্যবহার করেছি) সম্পদ লোড করা। একই নীতিটি কি প্রযোজ্য, বা এমন কোনও পরিস্থিতি রয়েছে যেখানে আপনি কলার বর্গ লোডারের পরিবর্তে প্রসঙ্গ শ্রেণীর লোডার মাধ্যমে সংস্থান গ্রহণ করতে চান?
ডিম হান্স

90

জাভাওয়াল্ড.কম এ একটি নিবন্ধ রয়েছে যা পার্থক্যটি ব্যাখ্যা করে => আপনার কোন ক্লাসলডার ব্যবহার করা উচিত

(1)

থ্রেড প্রসঙ্গ শ্রেণীবদ্ধরা শ্রেণিবদ্ধকরণ প্রতিনিধি প্রকল্পের চারপাশে একটি পিছনের দরজা সরবরাহ করে।

উদাহরণস্বরূপ জেএনডিআই নিন: এর সাহসগুলি আরটি.জারে বুটস্ট্র্যাপ ক্লাস দ্বারা প্রয়োগ করা হয়েছে (জেএসইএস ১.৩ দিয়ে শুরু করা), তবে এই মূল জেএনডিআই ক্লাসগুলি স্বাধীন বিক্রেতাদের দ্বারা প্রয়োগ করা জেএনডিআই সরবরাহকারীদের লোড করতে পারে এবং সম্ভাব্যভাবে অ্যাপ্লিকেশনটির-ক্লাসপ্যাটে মোতায়েন করা যেতে পারে। এই দৃশ্যে একটি প্যারেন্ট ক্লাসলোডারকে (এক্ষেত্রে আদিমতম) তার চাইল্ড ক্লাসলোডারগুলির মধ্যে একটিতে দৃশ্যমান কোনও শ্রেণি লোড করার জন্য আহ্বান জানানো হয়েছে (উদাহরণস্বরূপ, সিস্টেমটি)। সাধারণ জে 2 এসই প্রতিনিধি কাজ করে না এবং মূল জেএনডিআই ক্লাসগুলি থ্রেড কনটেক্সট লোডার ব্যবহার করতে পারে, সুতরাং যথাযথ প্রতিনিধি দলের বিপরীতে দিকনির্ধারিতভাবে শ্রেণিবোদ্ধার শ্রেণিবিন্যাসের মাধ্যমে কার্যকরভাবে "টানেলিং" করা হয়।

(২) একই উত্স থেকে:

এই বিভ্রান্তি সম্ভবত জাভার সাথে কিছু সময়ের জন্য থাকবে। যে কোনও প্রকারের গতিশীল রিসোর্স লোডিংয়ের সাথে কোনও জে 2 এসই এপিআই নিন এবং এটি কোন লোডিং কৌশল ব্যবহার করে তা অনুমান করার চেষ্টা করুন। এখানে একটি নমুনা দেওয়া হল:

  • জেএনডিআই প্রসঙ্গ শ্রেণীবদ্ধকারী ব্যবহার করে
  • Class.getResource () এবং Class.forName () বর্তমান ক্লাসলোডার ব্যবহার করে
  • জ্যাকএক্সপি প্রাসঙ্গিক ক্লাসলোডার ব্যবহার করে (J2SE 1.4 হিসাবে)
  • java.util.ResourceBundle কলারের বর্তমান শ্রেণি লোডার ব্যবহার করে
  • Java.protocol.handler.pkgs সিস্টেমের মাধ্যমে নির্দিষ্ট ইউআরএল প্রোটোকল হ্যান্ডলারগুলি কেবল বুটস্ট্র্যাপ এবং সিস্টেম ক্লাসলোডারগুলিতে সন্ধান করা হবে
  • জাভা সিরিয়ালাইজেশন এপিআই ডিফল্টরূপে কলারের বর্তমান ক্লাসলোডার ব্যবহার করে

যেহেতু প্রস্তাব দেওয়া হয়েছে যে মূল জেএনডিআই ক্লাসগুলি থ্রেড কনটেক্সট লোডার ব্যবহার করতে হবে তা আমি বুঝতে পারিনি যে এটি কীভাবে এই ক্ষেত্রে সহায়তা করে e আমরা প্যারেন্ট ক্লাসলোডার ব্যবহার করে প্রয়োগকারী বিক্রেতার ক্লাসগুলি লোড করতে চাই তবে তারা প্যারেন্ট ক্লাসলোডারের কাছে দৃশ্যমান নয় । সুতরাং আমরা কীভাবে প্যারেন্ট ব্যবহার করে এগুলি লোড করতে পারি, যদিও আমরা এই প্যারেন্ট ক্লাসলোডারকে থ্রেডের প্রসঙ্গে ক্লাসলোডার সেট করি।
সানি গুপ্ত

6
@ স্যাম, প্রস্তাবিত কর্মসংস্থানটি আসলে আপনি যা বলছেন তার থেকে সম্পূর্ণ বিপরীত। এটি bootstrapপ্রাসঙ্গিক শ্রেণি লোডার হিসাবে প্রাসঙ্গিক শ্রেণি লোডার হিসাবে সেট করা হচ্ছে না তবে এটির সাথে সেট করা হচ্ছে এমন শিশু systemশ্রেণিপথ শ্রেণি লোডার ThreadJNDIক্লাস তারপর ব্যবহার নিশ্চিত তৈরি করছেন Thread.currentThread().getContextClassLoader()JNDI বাস্তবায়ন শ্রেণীর ক্লাসপাথ উপলব্ধ লোড করা হয়নি।
রবি থাপলিয়াল

"নর্মাল জে 2 এসই প্রতিনিধি কাজ করে না", আমি জানতে পারি কেন এটি কাজ করে না? কারণ বুটস্ট্র্যাপের ক্লাসলোডার কেবল rt.jar থেকে ক্লাস লোড করতে পারে এবং অ্যাপ্লিকেশন -ক্লাসপাথ থেকে শ্রেণি লোড করতে পারে না? রাইট?
ইউফেং শেন 16

37

@ ডেভিড রাসেল উত্তরে যুক্ত করা, ক্লাসগুলি একাধিক শ্রেণীর লোডার দ্বারা লোড করা যেতে পারে।

শ্রেণি লোডার কীভাবে কাজ করে তা বুঝতে দিন ।

জাভেরিভিজেটে জাভিন পল ব্লগ থেকে:

এখানে চিত্র বর্ণনা লিখুন

এখানে চিত্র বর্ণনা লিখুন

ClassLoader তিনটি নীতি অনুসরণ করে।

ডেলিগেশন নীতি

জাভাতে একটি ক্লাস লোড করা হয়, যখন এটির প্রয়োজন হয়। ধরুন আপনার কাছে অ্যাবসি.ক্লস নামে একটি নির্দিষ্ট শ্রেণীর ক্লাস রয়েছে, এই শ্রেণিটি লোড করার প্রথম অনুরোধ অ্যাপ্লিকেশন ক্লাসলোডারে আসবে যা তার প্যারেন্ট এক্সটেনশন ক্লাসলোডারকে প্রেরণ করবে যা প্রিমর্ডিয়াল বা বুটস্ট্র্যাপ শ্রেণীর লোডারকে আরও প্রতিনিধি প্রেরণ করবে

  • বুটস্ট্র্যাপ ক্লাসলুডার আরটি.জার থেকে স্ট্যান্ডার্ড জেডিকে ক্লাস ফাইল লোড করার জন্য দায়বদ্ধ এবং এটি জাভার সমস্ত শ্রেণীর লোডারদের পিতা-মাতা। বুটস্ট্র্যাপ শ্রেণীর লোডারটির কোনও বাবা-মা নেই।

  • এক্সটেনশন ক্লাসলডার তার পিতামাতা, বুটস্ট্র্যাপে শ্রেণি লোডিংয়ের অনুরোধ পেশ করে এবং যদি ব্যর্থ হয় তবে ja.ext.dirs সিস্টেম সম্পত্তি দ্বারা নির্দেশিত অন্য কোনও ডিরেক্টরি ডিরেক্টরি Jre / lib / ext ডিরেক্টরি বা অন্য কোনও ডিরেক্টরি লোড করে class

  • সিস্টেম বা অ্যাপ্লিকেশন শ্রেণীর লোডার এবং এটি CLASSPATH এনভায়রনমেন্ট ভেরিয়েবল, -ক্লাসপাথ বা -cp কমান্ড লাইন বিকল্প, জেআর-এর ভিতরে ম্যানিফেস্ট ফাইলের ক্লাস-পাথ বৈশিষ্ট্য থেকে অ্যাপ্লিকেশন নির্দিষ্ট ক্লাস লোড করার জন্য দায়ী।

  • অ্যাপ্লিকেশন শ্রেণির লোডার হ'ল এক্সটেনশন ক্লাসলোডার এবং এটি sun.misc.Launcher$AppClassLoaderশ্রেণীর দ্বারা প্রয়োগ করা হয় ।

দ্রষ্টব্য: বুটস্ট্র্যাপ শ্রেণীর লোডার , যা বেশিরভাগ সিতে স্থানীয় ভাষায় প্রয়োগ করা হয়, বাদে সমস্ত জাভা শ্রেণি লোডার ব্যবহার করে প্রয়োগ করা হয় java.lang.ClassLoader

দৃশ্যমানতা নীতি

দৃশ্যমানতার নীতি অনুসারে, চাইল্ড ক্লাসলোডার প্যারেন্ট ক্লাসলোডার দ্বারা লোড হওয়া ক্লাস দেখতে পারে তবে তদ্বিপরীতটি সত্য নয়।

স্বতন্ত্রতা নীতি

এই নীতি অনুসারে প্যারেন্ট দ্বারা লোড করা একটি শ্রেণি আবার চাইল্ড ClassLoader দ্বারা লোড করা উচিত নয়

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.