2012-07-18 15 views
17

वहाँ 10 लाख लेख और डॉक्स वहाँ पर क्या जावा classloaders हैं कैसे/* क्यों * अपने खुद के लिखने के लिए है, और ... लेकिन वे सभी कुछ बातें संभालने जा सकता है कि मैं एक साधारण नहीं मिल सकता है लगता है को उत्तर!जावा क्लास लोडर कब संलग्न करते हैं?

मैं क्लासलोडर का काम समझता हूं: बाइटकोड पढ़ने और उससे ऑब्जेक्ट बनाने के लिए। विभिन्न classloaders अलग ढंग से ऐसा करते हैं, आदि

लेकिन मेरे अपने कोड में एक वर्ग लोडर एपीआई के खिलाफ कोड के लिए कभी नहीं किया था के बाद, और कभी नहीं मेरे अपने में से एक लिखने के लिए हो रही है, मैं समझने भारी कठिनाई हो रही है जब एक ClassLoader ' वास्तव में अपने कोड को आग लगती है।

उदाहरण के लिए:

public static void main(String[] args) { 
    Fizz fizz = new Fizz(); 
    fuzz.buzz(); 
} 

यहाँ, हम एक Fizz वस्तु है। Fizz से पहले तत्काल किया जा सकता है, हमें अपने कैश में Fizz.class को लात मारने और लोड करने के लिए क्लास लोडर की आवश्यकता है। यह कहां और कब हो रहा है?!? यह मेरे कोड में स्पष्ट रूप से स्पष्ट नहीं है, इसलिए यह अनिवार्य रूप से जेआरई में कहीं होना चाहिए ...?

उस प्रश्न का स्पर्शरेखा, अगर मैं अपने खुद के classloader लिखते हैं, कहते हैं, WidgetClassLoader और यह सब अपने आवेदन की कक्षाओं लोड करने के लिए या तो, या शायद सिर्फ अपनी Fizz.class, कैसे मैं अपने आवेदन में इस WidgetClassLoader "टाई" ऐसा कॉन्फ़िगर करना चाहते हैं यह जानता है कि कौन सा क्लासलोडर उपयोग करना है? क्या मेरे कोड को इस क्लासलोडर को स्पष्ट रूप से कॉल करने की आवश्यकता होगी या क्या यह पहले उदाहरण की तरह निहित होगा? अग्रिम में धन्यवाद!

+0

यह जेआरई में है, ज़ाहिर है। इसे पढ़ें, और कस्टम क्लास लोडर कॉन्फ़िगरेशन के लिए Google: http://www.javalobby.org/java/forums/t18345.html – duffymo

+0

@duffymo - कृपया आंद्रे के उत्तर के तहत मेरी टिप्पणी देखें - मेरे पास आपके लिए एक ही सवाल है! – IAmYourFaja

+0

मुझे अपने स्वयं के क्लास लोडर को कभी भी लिखने की ज़रूरत नहीं है। एक बार नहीं, पूरे समय में मैं जावा लिख ​​रहा हूं। और यह 1 99 7 में 1.0 के बाद से है। आपको क्या लगता है कि आपको इसकी आवश्यकता है? – duffymo

उत्तर

6

आप सवाल अब जितना छोटा हो उतना छोटा नहीं है।

आपका फिज उदाहरण: फ़िज़ लोड होने पर? यह JLS (Chapter 5.4: Linking) में परिभाषित किया गया है। यह परिभाषित नहीं करता है कि फिज लोड होने पर, लेकिन यह दृश्य व्यवहार के बारे में गारंटी देता है। 'कब' भाग के लिए, यदि फिज नहीं मिल पा रहा है, तो पहले अपवाद से एक अपवाद फेंक दिया जाएगा जो Fizz (Fizz fizz = new Fizz()) तक पहुंचता है। मुझे पूरा यकीन है कि यह विशेष रूप से इस मामले में नया Fizz() होगा क्योंकि अभिव्यक्ति का दाहिने तरफ पहले विकसित किया गया है।मामले में आप इसे इस तरह लिखा था:

Fizz fizz = null; 
fizz = new Fizz(); 

इस मामले में सीटी सीटी = अशक्त पहले से ही अपवाद फेंक क्योंकि सीटी वर्ग के लिए अपनी पहली पहुँच।

कौन फ़िज़ लोड करता है? जब एक वर्ग को लोड किया जाना चाहिए, वर्ग प्राप्त करने वाले कोड को 'संबंधित' श्रेणी का क्लास क्लास प्राप्त करने के लिए उपयोग किया जाता है। फिज उदाहरण में यह क्लासलोडर होगा जो मुख्य विधि के साथ कक्षा को लोड करेगा। बेशक, क्लासलोडर अपने पैरेंट क्लासलोडर को प्रतिनिधि चुनने का विकल्प चुन सकता है अगर वह खुद से फिज लोड नहीं कर सकता है।

मेरे क्लासलोडर का उपयोग करने के लिए मैं JVM कैसे प्राप्त करूं? स्पष्ट रूप से या स्पष्ट रूप से दो तरीके हैं। स्पष्ट रूप से: आप अपनी विधियों को कॉल करके अपने स्वयं के क्लासलोडर के माध्यम से कक्षा लोड कर सकते हैं। लागू: जब आप अपने क्लासलोडर से पहले से लोड किए गए वर्ग से कोड (अर्थ विधियों या प्रारंभकर्ताओं) को निष्पादित करते हैं और किसी क्लास संदर्भ को प्रक्रिया में हल करने की आवश्यकता होती है, तो आपके क्लासलोडर का स्वचालित रूप से उपयोग किया जाएगा क्योंकि यह क्लासलोडर है जो कोड को लोड करता है प्रथम स्थान।

+0

यह उस भाग का उत्तर देता है जो मुझे इस बारे में निश्चित नहीं था :-) –

+0

+1 "मेरे" क्लासलोडर 'थ्रेड.currentThread()। GetContextClassLoader() 'यानी प्रत्येक थ्रेड में डिफ़ॉल्ट क्लास लोडर है और कुछ भी नहीं है) वे अलग हो सकते हैं। –

+1

@ डुरंडल, फिज उदाहरण में स्पष्ट और निहित लोडिंग के बारे में, यह सुनिश्चित है कि कस्टम क्लास लोडर का उपयोग नहीं किया जाएगा .. सही? असल में, लागू लोडिंग के लिए, कहीं स्पष्ट लोडिंग प्रक्रिया को शुरू करना है। यहां या तो वह क्लास .forName() का उपयोग फिज क्लास के लिए स्पष्ट रूप से लोड करने के लिए कर सकते हैं या कक्षा पथ में फिज क्लास डाल सकते हैं ताकि JVM इसे लोड कर सके। निष्कर्ष यह है कि कस्टम क्लास लोडर केवल पहली बार स्पष्ट दृष्टिकोण के साथ काम करेगा। अगर मैं ग़लत हूं तो मेरी गलती सुझाएं। – AKS

3

जावा में एक डिफ़ॉल्ट क्लास लोडर है। यह डिफ़ॉल्ट वर्ग पथ में कक्षा घोषणाओं की तलाश करता है। यदि आप अपना खुद का वर्ग लोडर लिखते हैं तो आप पैरेंट क्लास लोडर सेट कर सकते हैं (और चाहिए)। यदि आपके पास कोई दूसरा नहीं है तो यह डिफ़ॉल्ट होगा। यदि आप ऐसा नहीं करते हैं तो आपका क्लास लोडर जावा एपीआई कक्षाएं नहीं ढूंढ पाएगा। यदि जावा एक कक्षा की तलाश में है तो यह आपके साथ कस्टम क्लास लोडर की तलाश शुरू नहीं करता है लेकिन पैरेंट क्लास लोडर के साथ। अगर इस माता-पिता के पास माता-पिता हैं तो यह वहां से शुरू होता है। केवल तभी जब कोई कक्षा नहीं मिल पाई तो अगले बच्चे वर्ग लोडर का उपयोग फिर से करने के लिए किया जाता है। फिर से यह तब तक जारी रहता है जब तक बच्चे हैं। यदि श्रृंखला श्रृंखला में किसी भी लोडर द्वारा नहीं मिली है, तो ClassNotFoundException फेंक दिया गया है।

बेशक जावा केवल आपके क्लास लोडर का उपयोग करता है यदि आप इसे डिफ़ॉल्ट श्रेणी लोडर के रूप में सेट करते हैं (Thread.currentThread().setContextClassLoader() पर कॉल करके) या कक्षा को मैन्युअल रूप से लोड करें (loadClass() पर कॉल करके)।

मुझे यकीन नहीं है कि कक्षा लोडर कब लागू किया जाता है। मुझे लगता है कि इसे या तो प्रोग्राम शुरू करने के लिए कहा जाता है (import के रूप में घोषित सभी वर्गों पर) या कक्षा (परिवर्तनीय घोषणा या कन्स्ट्रक्टर कॉल) के पहले उपयोग पर।

+0

धन्यवाद @ एंड्रे, लेकिन एक बार फिर, यह सवाल का जवाब है "* क्लासलोडर कैसे काम करते हैं? *" मैं समझता हूं क्लासलोडर पदानुक्रम - जो मुझे समझ में नहीं आता है वह कब और कहाँ जेआरई डिफ़ॉल्ट क्लासलोडर कोड को निष्पादित करता है जो मेरा 'Fizz.class' बनाता है। – IAmYourFaja

+0

'java.lang में ब्रेकपॉइंट सेट करने का प्रयास करें।'LoadClass() 'विधि में क्लासलोडर'। –

+0

मैंने इसे कुछ विचार दिया है और मेरा जवाब संपादित किया है। मुझे खेद है लेकिन मुझे उस अंतिम भाग पर यकीन नहीं है। –

0

कक्षा का वास्तविक निर्माण defineClass में होता है। कक्षा किसी भी स्रोत से किसी बाइट सरणी का उपयोग करके बनाई गई है।

सामान्य पथ defineClass को पाने के लिए (जो protected है) findClass (जो, ज़ाहिर है, भी protected है) के माध्यम से है। तो सामान्य प्रवेश बिंदु loadClass ->findClass ->defineClass है। लेकिन विशेष मामलों के लिए अन्य पथ हैं।

(पूरी बात काफी जटिल है, और परतों के रूप में जोड़ने की सुरक्षा को और अधिक जटिल हो गया का एक इतिहास और उपयोग के तरीके अधिक विविध प्रतिनिधित्व करता है।)

0

आप classloaders में रुचि रखते हैं और जब और वे कैसे काम , आप the OSGi specification भी देख सकते हैं - ऐसा लगता है कि यह आपके लिए एक बहुत ही रोचक पढ़ा जाएगा। ओएसजीआई जावा के लिए एक ढांचा है जो मॉड्यूलरिटी, स्पष्ट कोड अलगाव और जीवन चक्र प्रबंधन प्रदान करता है और जो इस समय बहुत लोकप्रिय है (उदा। ग्रहण स्वयं एक पर आधारित है)।

ओएसजीआई क्लासलोडर्स का भारी उपयोग करता है और स्पेस के अंदर क्लासलोडिंग के साथ सबकुछ कब और कैसे होता है, यह एक बहुत अच्छी व्याख्या है। असल में उनके पास प्रत्येक बंडल के लिए एक अलग बंडल क्लासलोडर होता है (इस प्रकार मॉड्यूल कहा जाता है) और ये क्लासलोडर्स निर्भरताओं का ख्याल रखते हैं और सही बंडल को दूसरे बंडल से लाते हैं।

संबंधित मुद्दे