2015-12-05 3 views
8

मैं जावा क्लास लोडर को ढूंढना या बनाना चाहता हूं जो केवल सिस्टम कक्षाओं को लोड करता है, एप्लिकेशन परिभाषित वर्ग पथ पर किसी भी वर्ग को छोड़कर। मेरा लक्ष्य उस वर्ग लोडर का उपयोग एक वर्ग लोडर बनाने के लिए करना है जो एक विशिष्ट जेएआर फ़ाइल से लोड होता है, सिस्टम-क्लास क्लास लोडर का उपयोग करके सिस्टम क्लास को हल करता है, लेकिन मेरे आवेदन द्वारा परिभाषित किसी भी कक्षा के साथ जेएआर फ़ाइल से कक्षाओं को दूषित नहीं करता है।जावा सिस्टम-केवल क्लास लोडर की आवश्यकता है

अभी तक मुझे सिस्टम-केवल क्लास लोडर बनाने का कोई तरीका नहीं मिला है जो या तो निजी एपीआई का उपयोग नहीं करता है या जावा कार्यान्वयन के बारे में धारणा नहीं करता है। नीचे दिए गए कोड को देखें जो मेरे वर्तमान माहौल में काम करता है लेकिन अवांछित मान्यताओं को बनाता है।

यदि कार्यान्वयन स्वतंत्र सिस्टम-केवल क्लास लोडर बनाने का कोई तरीका नहीं है, तो क्या ऐसा कोई कारण नहीं है? क्या मैं एक बुरा विचार करने की कोशिश कर रहा हूं?

private ClassLoader createJarClassLoader(File f) 
{ 
    ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); 
    if (systemClassLoader instanceof URLClassLoader) { 
     URLClassLoader cl = (URLClassLoader) systemClassLoader; 
     URL[] urls = cl.getURLs(); 
     List<URL> wantedURLs = new ArrayList<>(); 
     for (URL u : urls) { 
      if (isSystemURL(u)) { 
       wantedURLs.add(u); 
      } 
     } 
     try { 
      wantedURLs.add(f.toURI().toURL()); 
     } catch (MalformedURLException ex) { 
      return null; 
     } 
     return new URLClassLoader(wantedURLs.toArray(new URL[0]), null); 
    } 
    return null; 
} 

private boolean isSystemURL(URL u) 
{ 
    return u.getPath().contains("/jre/"); 
} 
+2

आप ऐसा करने की कोशिश क्यों कर रहे हैं? आप क्या करने की कोशिश कर रहे हैं? – jtahlborn

+0

@jtahlborn उन्होंने अपने कारणों को बहुत स्पष्ट रूप से दिया: "मेरा लक्ष्य है ..." – qqilihq

+1

@qqilihq - नहीं, ओपी ने "क्या" हासिल करने की कोशिश की थी, "क्यों" – jtahlborn

उत्तर

1

आपको पेरेंट क्लासलोडर बूटस्ट्रैप क्लासलोडर होने के लिए सेट करने की आवश्यकता है। बूटस्ट्रैप क्लासलोडर प्राप्त करने के लिए java.lang.String ऑब्जेक्ट पर getClassLoader() पर कॉल करें और अपने क्लासलोडर कन्स्ट्रक्टर में इसका उपयोग करें।

public class MyClassLoader extends URLClassLoader { 

    protected MyClassLoader(URL[] urls, ClassLoader parent) { 
     super(urls, parent); 
    } 

    static MyClassLoader getInstance(URL[] urls) { 
     ClassLoader parent = "".getClass().getClassLoader(); 
     return (new MyClassLoader(urls, parent)); 
    } 
} 

बूटस्ट्रैप classloader के प्रतिनिधित्व कार्यान्वयन निर्भर

कुछ कार्यान्वयन बूटस्ट्रैप वर्ग लोडर प्रतिनिधित्व करने के लिए अशक्त उपयोग कर सकते हैं के रूप में दर्ज है। यदि यह वर्ग बूटस्ट्रैप क्लास लोडर द्वारा लोड किया गया था तो यह विधि [getClassLoader] ऐसे कार्यान्वयन में शून्य वापस आ जाएगी।

लेकिन वही शब्द क्लासलोडर कन्स्ट्रक्टर में मूल क्लासलोडर पर लागू होता है, जिसका अर्थ यह है कि यह समाधान पोर्टेबल है।

+0

नहीं, हालांकि यह (ज्यादातर) जेडीके 8 में काम करता है, वहां इस बात की कोई गारंटी नहीं है कि बूटस्ट्रैप क्लास लोडर जावा प्लेटफॉर्म के सभी वर्गों के बारे में जानता है; जेडीके 9 के लिए मॉड्यूलर जेडीके की योजना बनाई गई, यह निश्चित रूप से नहीं होगी। क्लासलोडर कन्स्ट्रक्टर को पास होने पर अधिक दिलचस्प सवाल यह है कि क्या शून्य मतलब है। मुझे इसका अर्थ यह नहीं है कि इसका क्या मतलब है, लेकिन शायद इसे क्लास लोडर को इंगित करने के लिए परिभाषित किया जा सकता है जो जावा प्लेटफॉर्म में बिल्कुल कक्षाओं को जानता है, और नहीं। –

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