2013-08-24 7 views
6

में फ़ाइल की बाइट सरणी लोड करें मैं एचडीडी को छोड़ दिए बिना सीधे एक जार फ़ाइल लोड करने की कोशिश कर रहा हूं। मैंने क्लासलोडर का उपयोग करने का प्रयास किया है, लेकिन मुझे एक त्रुटि मिलती है।मेमोरी

यह मेरा कोड है:

कस्टम classloader

public class CLS_ClassLoader extends ClassLoader { 

    private byte[] bArrData; 

    public CLS_ClassLoader(ClassLoader parent, byte[] bArrData) { 
     super(parent); 

     this.bArrData = bArrData; 
    } 

    public Class<?> loadClass(String name) throws ClassNotFoundException { 
     return defineClass(name, bArrData, 0, 
       bArrData.length); 
    } 
} 

मुख्य

ClassLoader tParentClsLoader = CLS_ClassLoader.class.getClassLoader(); 
CLS_ClassLoader tClsLoader = new CLS_ClassLoader(tParentClsLoader, fileToByteArray("D:/App.jar")); 
Class<?> tClass = null; 

try { 
     tClass = tClsLoader.loadClass("pkg_main.CLS_Main"); 
} catch (ClassNotFoundException e) { 
    e.printStackTrace(); 
} 

आउटपुट

Exception in thread "main" java.lang.ClassFormatError: Incompatible magic value 1347093252 in class file pkg_main/CLS_Main 
    at java.lang.ClassLoader.defineClass1(Native Method) 
    at java.lang.ClassLoader.defineClass(Unknown Source) 
    at java.lang.ClassLoader.defineClass(Unknown Source) 
    at pkg_main.CLS_ClassLoader.loadClass(CLS_ClassLoader.java:20) 
    at pkg_main.CSL_Main.main(CSL_Main.java:27) 

मेरा विचार एन्क्रिप्टेड जार फ़ाइल लेना है, इसे रनटाइम पर डिक्रिप्ट करना और सीधे मेमोरी में लोड करना है।

टाइपो के लिए खेद है, मैंने अंग्रेजी अच्छी तरह से बात नहीं की थी। अग्रिम में धन्यवाद!

+1

* "मैं HDD करने के लिए इसे छोड़ने के बिना सीधे स्मृति में एक जार फ़ाइल को लोड करने की कोशिश कर रहा हूँ "* उन बाइट ** ** से कहां आ रहे हैं? एक यूआरएल? स्मृति में संकलित? पिक्सीज़? * "मेरा विचार एन्क्रिप्टेड जार फ़ाइल लेना है, इसे रनटाइम पर डिक्रिप्ट करना और सीधे मेमोरी में लोड करना है।" * यह एक खराब विचार है। यदि इसका मतलब लोगों को 'चोरी/रिवर्स इंजीनियरिंग कोड' को रोकने के लिए है, तो यह केवल हैकर्स के सबसे शौकिया को रोक देगा। यह हैकर्स भी मध्यम क्षमता के साथ आपको चिंता करने की ज़रूरत है। –

+0

क्या आपने सोर्स कोड पढ़ा था जिसे मैंने चिपकाया था? अगर आपने पढ़ा है कि आपने "फाइल टूबेटएरे (" डी:/ऐप.जर ")" देखा होगा। मैंने कहा, मैं सीधे बाइट सरणी को स्मृति में लोड करना चाहता हूं। और मुझे लगता है कि मेरे कोड को अपघटन से बचाने के लिए एक अच्छा विचार होगा। यह डिकंपाइल जावा को जानने के लिए हैकर नहीं लेता है। धन्यवाद। –

+1

@ सैमुएलपेड्रोसा शायद यह उत्तर मदद करेगा: http://stackoverflow.com/a/6797331/1531054। '.jar' से' .class' फ़ाइल को अनजिप करने का प्रयास करें और फिर क्लास लोडर को इसके बाइट सरणी को फ़ीड करें। –

उत्तर

3

आपकी मुख्य गलती यह है कि defineClass (...) कक्षा बाइट्स की अपेक्षा कर रहा है और आप इसे पूरी जार फ़ाइल से खिला रहे हैं। वास्तविक अपवाद फेंक दिया जाता है यदि क्लास बाइट 0xCAFEBABE, सामान्य जावा क्लास फ़ाइल हेडर से शुरू नहीं होता है। इसलिए, आपको जार फ़ाइल से कक्षाओं को सॉर्ट करने के लिए एक अतिरिक्त चरण की आवश्यकता है। निम्नलिखित कार्यान्वयन को दर्शाता है विचार:

class CCLoader extends ClassLoader { 
    private Map<String, byte[]> classes = new HashMap<String, byte[]>(); 

    public CCLoader(InputStream in) { 
     super(CCLoader.class.getClassLoader()); 
     try { 
      JarInputStream jis = new JarInputStream(in); 
      JarEntry je = null; 
      String entryName = null; 
      while ((je = jis.getNextJarEntry()) != null) { 
       entryName = je.getName(); 
       if (je.getName().endsWith(".class")) { 
        byte[] classBytes = readClass(jis); 
        String canonicalName = entryName.replaceAll("/", ".").replaceAll(".class", ""); 
        classes.put(canonicalName, classBytes); 
       } 
      } 
      jis.close(); 
      in.close(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    private byte[] readClass(InputStream stream) throws IOException { 
     ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
     while(true){ 
      int qwe = stream.read(); 
      if(qwe == -1) break; 
      baos.write(qwe); 
     } 
     return baos.toByteArray(); 
    } 

    public Class loadClass(String name) throws ClassNotFoundException { 
     try { 
      return this.getParent().loadClass(name); 
     } catch (ClassNotFoundException e) { 
      return findClass(name); 
     } 
    } 

    public Class findClass(String name) throws ClassNotFoundException { 
     byte[] classBytes = classes.get(name); 
     return defineClass(name, classBytes, 0, classBytes.length); 
    } 

} 

अपने उदाहरण के बाद आप इसे इस तरह की कोशिश कर सकते हैं:

ClassLoader tClsLoader = new CCLoader(new FileInputStream("C:/commons-io-2.0.1.jar")); 
Class<?> tClass = tClsLoader.loadClass("org.apache.commons.io.FileExistsException"); 
+0

मैं इसे आज़माउंगा, धन्यवाद :) –

+0

मुझे यह त्रुटि मिलती है: java.lang.NegativeArraySizeException \t pkg_main.CCLoader पर। (CCLoader.java:26) \t pkg_main.CSL_Main.main (CSL_Main.java:23) –

+0

पसंद है, इसे कक्षा फ़ाइल का आकार नहीं मिल सकता है। –

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