জাভা, ক্লাসপাথ, শ্রেণিবদ্ধকরণ => একই জারে / প্রকল্পের একাধিক সংস্করণ


117

আমি জানি এটি অভিজ্ঞ কোডারদের জন্য একটি নির্বোধ প্রশ্ন হতে পারে। তবে আমার কাছে একটি লাইব্রেরি রয়েছে (একটি HTTP ক্লায়েন্ট) যা আমার প্রকল্পে ব্যবহৃত অন্যান্য ফ্রেমওয়ার্ক / জারের কয়েকটি প্রয়োজন। তবে তাদের সবার জন্য বিভিন্ন বড় সংস্করণ যেমন:

httpclient-v1.jar => Required by cralwer.jar
httpclient-v2.jar => Required by restapi.jar
httpclient-v3.jar => required by foobar.jar

শ্রেণিবদ্ধার কি কোনওভাবে তাদের আলাদা করার মতো বুদ্ধিমান? সম্ভবত না? ক্লাসলোডার কীভাবে এটি পরিচালনা করে, যদি তিনটি জারে কোনও শ্রেণি একই হয়। কোনটি বোঝাই হয় এবং কেন?

ক্লাসলোডার কেবল একটি জার পিকআপ করে বা এটি নির্বিচারে ক্লাসগুলি মিশ্রিত করে? সুতরাং উদাহরণস্বরূপ, যদি সংস্করণ -১.জার থেকে কোনও শ্রেণি লোড করা হয়, একই শ্রেণি লোডার থেকে লোড হওয়া সমস্ত অন্যান্য ক্লাসগুলি কি একই জারে যাবে?

আপনি এই সমস্যাটি কীভাবে পরিচালনা করবেন?

জারগুলিকে "প্রয়োজনীয়.জার" এর মধ্যে "অন্তর্ভুক্ত" করার কোনও কৌশল আছে যাতে এটি "একক / প্যাকেজ" হিসাবে দেখা হয় Classloader, বা কোনওভাবে সংযুক্ত?

উত্তর:


57

ক্লাসলোডার সম্পর্কিত সমস্যাগুলি একটি বেশ জটিল বিষয়। আপনার যে কোনও ক্ষেত্রে কিছু তথ্য মাথায় রাখা উচিত:

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

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

  • জাভা ভাষার স্পেসিফিকেশন অনুসারে, বর্গ বাইনারি নামের জন্য কোনও স্বতন্ত্রতা বাধা নেই, তবে যতদূর আমি দেখতে পাচ্ছি, প্রতিটি শ্রেণিবদ্ধের জন্য এটি অনন্য হওয়া উচিত।

আমি একই বাইনারি নাম সহ দুটি ক্লাস লোড করার একটি উপায় বের করতে পারি এবং এতে দুটি পৃথক শ্রেণি লোডার ডিফল্ট আচরণকে ওভাররাইড করে তাদের (এবং তাদের সমস্ত নির্ভরতা) লোড করা জড়িত। মোটামুটি উদাহরণ:

    ClassLoader loaderA = new MyClassLoader(libPathOne);
    ClassLoader loaderB = new MyClassLoader(libPathTwo);
    Object1 obj1 = loaderA.loadClass("first.class.binary.name", true)
    Object2 obj2 = loaderB.loadClass("second.class.binary.name", true);

আমি সর্বদা ক্লাসলোডার কাস্টমাইজেশনটিকে একটি কঠিন কাজ পেয়েছি। আমি বরং সম্ভব হলে একাধিক বেমানান নির্ভরতা এড়াতে পরামর্শ দিই।


13
বুটস্ট্র্যাপ শ্রেণীর লোডার যথাযথভাবে প্রতিনিধিত্ব করে। আপনি যখন নতুন ক্লাস ইনস্ট্যান্ট করবেন তখন আরও সুনির্দিষ্ট ক্লাসলোডারকে ডাকা হবে। আপনি যে ক্লাসটি লোড করার চেষ্টা করছেন তার কোনও রেফারেন্স যদি এটি খুঁজে না পায় তবে এটি তার পিতামাতার কাছে প্রতিনিধি প্রেরণ করুন দয়া করে আমাকে সহ্য করুন তবে এটি ক্লাসলোডার নীতিতে নির্ভর করে যা ডিফল্ট পিতা-মাতার প্রথম হয়। অন্য কথায় শিশু শ্রেণি প্রথমে তার পিতামাতাকে ক্লাসটি লোড করতে জিজ্ঞাসা করবে এবং সম্পূর্ণ শ্রেণিবদ্ধ এটি লোড করতে ব্যর্থ হলেই লোড হবে, না ??
ডেকরাজরাজ

5
না - সাধারণত কোনও শ্রেণীবদ্ধার ক্লাস নিজেই অনুসন্ধান করার আগে তার পিতামাতার কাছে প্রতিনিধি। ক্লাসলোডারের জন্য ক্লাস জাভাদোক দেখুন।
জো কেয়ার্নি

1
আমি মনে করি টমক্যাটটি এখানে বর্ণিত পদ্ধতিতে এটি করে তবে "প্রচলিত" প্রতিনিধি
দলটি

@ ডেককরাজ: কিছুটা গুগল করার পরে আমি ওরেकल ডক্স থেকে এটি পেয়েছি: "প্রতিনিধি নকশায় কোনও শ্রেণি লোডার একটি শ্রেণি নিজেই লোড করার চেষ্টা করার আগে তার পিতাকে ক্লাসলোডিং প্রতিনিধিত্ব করে [[...] যদি পিতামাত্ত শ্রেণীর লোডার কোনও শ্রেণি লোড করতে না পারে, ক্লাস লোডার ক্লাস নিজেই লোড করার চেষ্টা করে effect ফলস্বরূপ, কোনও শ্রেণি লোডার পিতামাতার কাছে উপলভ্য নয় কেবল ক্লাসগুলি লোড করার জন্য দায়বদ্ধ " আমি আরও তদন্ত করব। এটি যদি ডিফল্ট বাস্তবায়ন হিসাবে আবির্ভূত হয় তবে আমি সেই অনুযায়ী প্রতিক্রিয়া আপডেট করব। ( ডকস.ওরাকল.কম / ই 19501-01 / 819-3659 / beadf / index.html )
লুকা পুতজু

20

প্রতিটি ক্লাসলোড হুবহু একটি ক্লাস বাছাই করে। সাধারণত প্রথমটি পাওয়া যায়।

ওএসজি একই জারের একাধিক সংস্করণের সমস্যা সমাধান করা। ইকুইনক্স এবং অ্যাপাচি ফেলিক্স হ'ল ওএসজিআইয়ের সাধারণ ওপেন সোর্স বাস্তবায়ন।


6

ক্লাসলোডার জার থেকে ক্লাসগুলি লোড করবে যা ক্লাসপথে প্রথম হয়েছিল। সাধারণত, লাইব্রেরির অসামঞ্জস্যিত সংস্করণগুলির প্যাকেজগুলির মধ্যে পার্থক্য থাকতে পারে, তবে সম্ভাব্য ক্ষেত্রে যদি তারা সত্যিই বেমানান থাকে এবং এক সাথে প্রতিস্থাপন করা যায় না - চেষ্টা করুন জারজার।


6

শ্রেণিবদ্ধরা চাহিদা অনুযায়ী ক্লাস লোড করেন। এর অর্থ হল আপনার অ্যাপ্লিকেশন এবং সম্পর্কিত লাইব্রেরি দ্বারা প্রয়োজনীয় ক্লাসটি অন্যান্য শ্রেণীর আগে লোড করা হবে; নির্ভরশীল ক্লাসগুলি লোড করার অনুরোধটি সাধারণত নির্ভরশীল শ্রেণীর লোডিং এবং লিঙ্কিংয়ের প্রক্রিয়া চলাকালীন জারি করা হয়।

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

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


1

URLClassLoaderজারগুলির ডিফ -২ সংস্করণ থেকে ক্লাসগুলি লোড করার জন্য আপনি প্রয়োজনীয়গুলি ব্যবহার করতে পারেন :

URLClassLoader loader1 = new URLClassLoader(new URL[] {new File("httpclient-v1.jar").toURL()}, Thread.currentThread().getContextClassLoader());
URLClassLoader loader2 = new URLClassLoader(new URL[] {new File("httpclient-v2.jar").toURL()}, Thread.currentThread().getContextClassLoader());

Class<?> c1 = loader1.loadClass("com.abc.Hello");

Class<?> c2 = loader2.loadClass("com.abc.Hello");

BaseInterface i1 = (BaseInterface) c1.newInstance();

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