2010-11-04 13 views
25

सभी को नमस्कार और ध्यान के लिए धन्यवाद! मुझे एक समस्या है जो दोनों आसान और स्पष्ट होनी चाहिए, फिर भी मैं अटक गया हूं।कस्टम क्लासलोडर का उपयोग करने के लिए कैसे करें?

मैं एक कस्टम क्लासलोडर के माध्यम से किसी तृतीय पक्ष लाइब्रेरी द्वारा उपयोग किए जाने वाले गतिशील रूप से बनाए गए जावा वर्गों को वितरित करना चाहता हूं।

अब मेरी समस्या यह है कि: मैं अपने क्लास को लोड करने के लिए अपने कस्टम क्लासलोडर को कैसे सेट करूं? जब मैं उन्हें सीधे लोड नहीं करता हूं?

मैंने सोचा कि जब मैंने अपने क्लासलोडर का उपयोग एक निश्चित वर्ग को लोड करने के लिए किया था, तो यह कक्षा का क्लासलोडर बन गया, और उस वर्ग से लोड की गई सभी कक्षाओं को मेरे क्लासलोडर के माध्यम से चैनल किया जाएगा।

मैंने इस आधिकारिक ट्यूटोरियल के बाद एक कस्टम क्लासलोडर बनाया: http://java.sun.com/developer/onlineTraining/Security/Fundamentals/magercises/ClassLoader/help.html

public class DynamicClassloader extends ClassLoader { 

    private Map<String, Class<?>> classesMap = new HashMap<String, Class<?>>(); 

    public DynamicClassloader(ClassLoader parent) { 
     // Also tried super(parent); 
     super(sun.misc.Launcher.getLauncher().getClassLoader()); 
    } 

    // Adding dynamically created classes 
    public void defineClass(String name, Class<?> clazz) { 
     classesMap.put(name, clazz); 
    } 

    @Override 
    protected Class<?> findClass(String name) throws ClassNotFoundException { 
     // load from parent 
     Class<?> result = findLoadedClass(name); 
     if (result != null) { 
      return result; 
     } 
     try { 
      result = findSystemClass(name); 
     } catch (Exception e) { 
      // Ignore these 
     } 
     if (result != null) { 
      return result; 
     } 
     result = classesMap.get(name); 
     if (result == null) { 
      throw new ClassNotFoundException(name); 
     } 
     return result; 
    } 
} 

मैं इस तरह कोड में कहीं और उपयोग करना चाहता था:

ClassLoader thisClassLoader = this.getClass().getClassLoader(); 
((DynamicClassloader) thisClassLoader).defineClass(className, dynClass); 
अब

मेरी समस्या यह है कि जब मैं 3 पार्टी पुस्तकालय वर्ग के findSystemClass(name) फोन, माता पिता classloader इस वर्ग पाता है (क्योंकि यह कक्षापथ पर है) और इसके क्लासलोडर बन जाता है। और चूंकि अभिभावक क्लासलोडर को मेरे कस्टम क्लासलोडर के बारे में पता नहीं है, इसलिए इसे प्रभावी रूप से उपयोग से बाहर कर दिया गया है और this.getClass().getClassLoader() को डायनामिक क्लासलोडर पर नहीं डाला जा सकता है।

एक और तरीका मेरे क्लासलोडर को जेवीएम तर्क -Djava.system.class.loader=my.DynamicClassloader के माध्यम से सिस्टम क्लासलोडर होने के लिए सेट करना होगा।

... 
at de.unisaarland.cs.st.DynamicClassloader.findClass(DynamicClassloader.java:39) 
at java.lang.ClassLoader.loadClass(ClassLoader.java:307) 
at java.lang.ClassLoader.loadClass(ClassLoader.java:248) 
at java.lang.ClassLoader.findSystemClass(ClassLoader.java:916) 
at de.unisaarland.cs.st.DynamicClassloader.findClass(DynamicClassloader.java:39) 
    ... 

यह क्या करने के लिए वास्तव में आसान होना चाहिए, फिर भी मैं अब विचारों से बाहर हूँ ... किसी भी मदद बहुत सराहना कर रहा है: लेकिन है कि मुझे एक StackOverflowError देता है!

+0

संबंधित http://stackoverflow.com को/प्रश्न/6366288/कैसे-टू-चेंज-डिफॉल्ट-क्लास-लोडर-इन-जावा, http://stackoverflow.com/questions/5380275/replacement-system-classloader-for-classes-in-jars-containing-jars/19128964 # 191 28 9 64 और http: // stackoverflow।com/प्रश्न/5380275/प्रतिस्थापन-प्रणाली-classloader-वर्गों में जार युक्त-जार के लिए। – roesslerj

उत्तर

19

सुनिश्चित नहीं है कि मैं प्रश्न समझता हूं, आपके पास तीसरे पक्ष की lib है और आप कक्षाओं को लोड करने के लिए अपने क्लासलोडर का उपयोग करना चाहते हैं।

आप भाग्यशाली हैं, तो तीसरे पक्ष lib धागे संदर्भ classloader जो आप Thread.currentThread().setContextClassLoader(myClassLoader) का उपयोग कर सेट कर सकते हैं एक ही धागे में आप Thread.currentThread().getContextClassLoader() के साथ इस classloader उपयोग कर सकते हैं ...

एक और मुद्दा है, लेकिन यकीन है कि यह नहीं का उपयोग करता है

: अपने संदर्भ में महत्वपूर्ण है, यह है कि आप भी एक अभिभावक पिछले classloader कि अपनी मूल को सौंपने (बजाय पहले को सौंपने के लिए कोशिश कर रहा है)

अपनी टिप्पणी के बाद संपादित से पहले वर्ग लोड करने के लिए कोशिश करेंगे लिख सकते हैं

parent_last क्लासलोडर एक फर्क पड़ता है यदि आपकी लाइब्रेरी थ्रेड संदर्भ क्लासलोडर पर भरोसा नहीं करती है, तो आपको लाइब्रेरी को अपने माता-पिता-अंतिम क्लासलोडर के साथ लोड करना होगा, इस प्रकार अपने क्लासलोडर को इसके मूल लोडर की बजाय लाइब्रेरी के लिए क्लासलोडर के रूप में सेट करना होगा (अपने classloader) की मूल ...

तुम भी एक माता पिता की पहली व्यवहार के साथ, लेकिन अपने 3 पार्टी पुस्तकालय के लिए एक classloader कर सकते हैं ...

And a good link about classloaders...

+0

ContextClassLoader एक अच्छा विचार है, इसे आज़माएं। आपका बहुत बहुत धन्यवाद! माता-पिता के आखिरी क्लासलोडर के लिए: मुझे नहीं लगता कि इससे कोई फर्क पड़ेगा। मैं वास्तव में उस वर्ग को परिभाषित नहीं करना चाहता हूं जिसे मैं लोड कर रहा हूं, मैं केवल अपने क्लासलोडर को मौजूदा क्लासलोडर बनना चाहता हूं, इसलिए 'findClass' के बाद की सभी कॉलों को इसके माध्यम से चैनल किया जाता है ... – roesslerj

+0

आप माता-पिता-अंतिम कक्षा कैसे लिखते हैं लोडर? क्या कोई मौजूदा कार्यान्वयन नहीं है? यदि नहीं, तो या तो यह एक कॉमॉम समस्या नहीं है या इसे हल करने का एक और बेहतर तरीका है। –

+0

लिंक मृत – grimmeld

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