हाथ की स्थिति उतनी सरल नहीं है जितनी शीर्षक का संकेत मिलता है।मैं कैसे नियंत्रित करूं कि क्लासलोडर कक्षा को लोड करता है?
जावा 1.6_17 जेडब्ल्यूएस के माध्यम से चल रहा है।
मेरे पास एक कक्षा है, MyClass
कहें और इसके उदाहरण सदस्य चर में से एक एक गलती तृतीय पक्ष लाइब्रेरी से एक प्रकार है जहां कक्षा प्रारंभिकता के दौरान यह गतिशील रूप से Class.forName(String)
के साथ अपने कुछ वर्गों को लोड करने का प्रयास करता है। इन मामलों में से एक में गतिशील रूप से कॉल होता है: Class.forName("foo/Bar")
। यह कक्षा का नाम बाइनरी नामों के लिए जेएलएस का पालन नहीं करता है और अंत में java.lang.NoClassDefFoundError: foo/Bar
तक जाता है।
हमारे पास एक कस्टम ClassLoader
है जिसे मैंने ClassLoader.findClass(String)
और ClassLoader.loadClass(String)
पर एक sanitize विधि जोड़ा है जो इस समस्या को हल करता है। myCustomClassLoader.findClass("foo/Bar")
कौन सा तो बिना किसी समस्या के वर्ग लोड करता है:
मैं की तरह सामान कॉल कर सकते हैं। लेकिन अगर मैं समय से पहले कक्षा को लोड करता हूं, तो भी मुझे बाद में अपवाद मिलता है। ऐसा इसलिए है क्योंकि MyClass
की शुरुआत के दौरान Bar
- को उनके कोड को किसी स्थिर ब्लॉक में Class.forName("foo/Bar")
पर कॉल करना समाप्त होता है। यह वास्तव में ठीक होगा अगर क्लासलोडर इसका उपयोग करने का प्रयास कर रहा था तो मेरा कस्टम क्लास लोडर था। लेकिन यह नहीं है। यह com.sun.jnlp.JNLPClassLoader
है जो इस तरह की स्वच्छता नहीं करता है, इस प्रकार मेरी समस्या।
मैंने यह सुनिश्चित किया है कि Thread.currentThread().getContextClassLoader()
मेरे कस्टम क्लास लोडर पर सेट है। लेकिन यह (जैसा कि आप जानते हैं) का कोई प्रभाव नहीं पड़ता है। मैंने इसे पढ़ने वाली कुछ चीजों के कारण main()
में पहली चीज़ के रूप में भी सेट किया है, MyClass.class.getClassLoader()
- जेएनएलपी क्लासलोडर है। अगर मैं इसे जेएनएलपी क्लासलोडर नहीं बन सकता और इसके बजाय मेरा उपयोग करने के लिए मजबूर कर सकता हूं, समस्या हल हो जाती है।
मैं क्लासलोडर को कक्षा प्रारंभ करने के दौरान क्लास लोड करने के लिए किस क्लासलोडर का उपयोग अपनी स्थिर कक्षा के माध्यम से कक्षा लोड करने के लिए किया जाता है .forName ("foo/bar") कॉल प्रारंभिकरण के दौरान किया गया है? मुझे विश्वास है कि अगर मैं अपने कस्टम क्लास लोडर को वापस करने के लिए MyClass.class.getClassLoader()
को मजबूर कर सकता हूं, तो मेरी समस्या हल हो जाएगी।
यदि किसी के पास विचार है तो मैं अन्य विकल्पों के लिए खुला हूं।
टीएल; डीआर: मेरी पसंद के क्लासलोडर का उपयोग करने के लिए MyClass
द्वारा संदर्भित सभी Class.forName(String)
कॉल को तीसरी पार्टी लाइब्रेरी में कॉल करने में सहायता करें।
* "एक गलती तृतीय पक्ष लाइब्रेरी से" * अंततः सबसे अच्छी रणनीति, उस एपीआई को प्रतिस्थापित करना है। –
@AndrewTompson यह उस पर आ सकता है। मुझे आशा है कि यह नहीं है। तो अगर किसी के पास कोई विचार है - मैं सभी कान हूँ! –
मैंने बूटस्ट्रैप क्लास बनाने और वहां से हमारे सभी बाहरी पुस्तकालयों को लोड करने के लिए URLClassLoader का उपयोग करके कुछ ऐसा किया। बूस्टरपैप क्लास लॉन्च होने पर वे क्लासपाथ में नहीं हैं, इसलिए वे देखे जाने वाले एकमात्र क्लासलोडर कस्टम हैं। कोई जवाब नहीं है क्योंकि मुझे नहीं पता कि यह जेडब्ल्यूएस के साथ काम करेगा या नहीं। हमने इसे रनटाइम पर प्लगइन लाइब्रेरी लोड करने के लिए किया था। – Thomas