2010-08-08 6 views
5

को हुक नहीं कर रहा है मैं एक कस्टम क्लासलोडर को परिभाषित करने की कोशिश कर रहा हूं।ContextClassLoader

public class ExampleLoader extends ClassLoader 
{ 
    public Class<?> findClass(String name) throws ClassNotFoundException 
    { 
     System.out.println("This never gets printed"); 
     return super.findClass(name); 
    } 

    public Class<?> loadClass(String name, boolean b) 
     throws ClassNotFoundException 
    { 
     System.out.println("This never gets printed"); 
     return super.loadClass(name, b); 
    } 
} 

और निश्चित रूप से मेरी कोड यह परीक्षण करने के लिए:

public class Tester 
{ 
    public static void main(String[] args) 
    { 
     Thread t = new FooThread(); 
     t.setContextClassLoader(new ExampleLoader()); 
     t.start(); 
    } 
} 

class FooThread extends Thread 
{ 
    public void run() 
    { 
     new RandomClass(); 
    } 
} 

समस्या यह है कि मेरी लाइनों मुद्रित कभी नहीं मिलता है। जाहिर है मैं कुछ याद कर रहा हूँ।

उत्तर

6

यह bug 4868493 से संबंधित है। यहाँ एक प्रासंगिकता के हवाला देते है:

दुर्भाग्य getContextClassLoader और setContextClassLoader के लिए दस्तावेज़ निष्कर्ष है कि सबमिट करने वाले कोड अपेक्षित ढंग से काम करना चाहिए करने के लिए एक हो सकती है।

हालांकि, वहाँ वर्ग लोड हो रहा है में एक बुनियादी नियम है - कोई वर्ग कभी स्वचालित रूप से एक वर्ग है जो "अनुप्रवाह" है, यानि कि जो सीधे उस वर्ग 'ClassLoader या अपने पूर्वज ClassLoaders में से एक द्वारा लोड नहीं जा सकती है, लोड कर सकते हैं।

यह कई स्थानों में वर्णित है। उदाहरण के लिए, पर यहां उपलब्ध श्वेत पत्र पर ध्यान दें: http://www.javageeks.com/Papers/ClassForName/index.html ज्ञान प्राप्त करने के लिए।

मुख्य बिंदु यह प्रतीत होता है कि संदर्भ वर्ग लोडर का उपयोग जावा भाषा द्वारा स्वचालित रूप से नहीं किया जाता है। यह पर केवल एक पारंपरिक स्थान है जो संदर्भ वर्ग लोडर को संग्रहीत करता है ताकि अन्य वर्ग 3-argument form of Class.forName के साथ इसका उपयोग कर सकें।

कल्पना Thread.getContextClassLoader और Thread.setContextClassLoader के लिए स्पष्ट किया जाना चाहिए, और "संदर्भ वर्ग लोडर" अर्थ स्पष्ट किया जाना चाहिए। एक दस्तावेज़ बग के रूप में पुन: वर्गीकरण।

spec अभी तक स्पष्ट नहीं किया गया है।

This never gets printed
+0

जिज्ञासा से बाहर, कैसे बिलाव जैसे अनुप्रयोगों यह काम कर सकता हूँ? मेरी समझ यह है कि सभी टॉमकैट वेबएप एक साझा जेवीएम के भीतर से चलते हैं, लेकिन जब वे कक्षाओं का उपयोग करते हैं, तो कक्षा परिभाषाएं उनके संबंधित युद्धों से आती हैं। कोई विचार है कि वे इसे कैसे प्राप्त करते हैं? – Jim

+2

वे 'क्लासलोडर # लोड क्लास() 'का उपयोग करते हैं। 'क्लासलोडर' उदाहरण इस तरह से धागे में संग्रहीत और पास किया जाता है। स्रोत कोड में देखने के लिए एक अच्छा प्रारंभिक बिंदु 'org.apache.catalina.core.DefaultInstanceManager' है। – BalusC

0

आम तौर पर, एक JVM में सभी classloaders एक में व्यवस्थित होते हैं:

यह द्वारा

Class.forName(RandomClass.class.getName(), 
       true, 
       getContextClassLoader()).newInstance(); 

काम क्या आप शुरू में चाहते हैं, की जगह new RandomClass() यह प्रिंट, विरोध रूप में, निम्नलिखित में जाने के लिए पदानुक्रम जैसे कि प्रत्येक क्लासलोडर (प्राइमोरियल क्लासलोडर को छोड़कर जो पूरे जेवीएम को बूटस्ट्रैप करता है) में एक ही माता-पिता होता है। जब कक्षा को लोड करने के लिए कहा जाता है, तो प्रत्येक अनुपालन क्लासलोडर से पहले अपने माता-पिता को लोडिंग का प्रतिनिधि होने की उम्मीद है और केवल माता-पिता विफल होने पर कक्षा को परिभाषित करने का प्रयास किया जाता है।

आपके मामले में वही बात हो रही है। "RandomClass" लोड किया जाना है, ContextClassLoader अपने माता-पिता को इस तरह से प्रतिनिधि करता है। और पैरेंट क्लास लोडर में से एक "RandomClass" लोड करने में सक्षम था (RandomClass पैरेंट के क्लासपाथ में था)। इस कारण से आपका एसओपी दिखाई नहीं देता है।लेख निम्नलिखित

संदर्भ थोड़ा पुराने लेकिन अच्छा:

http://www.javaworld.com/javaworld/javaqa/2003-06/01-qa-0606-load.html?page=1