5

तो अभी, मुझे लगता है कि ObjectInputStream और ObjectOutputStream साथ चल रहा है एक सर्वर है।सॉकेट पर एक बेनामी वर्ग भेजें? (जावा में Object..Stream)

मेरी समस्या यह है कि मेरे पास एक कस्टम (अज्ञात) कक्षा है जो java.lang.Date को बढ़ाती है जिसे मैं क्लाइंट को भेजने और फिर संकलित करने की कोशिश कर रहा हूं।

तो कहीं नहीं मैंने कभी ग्राहक के पक्ष वर्ग को परिभाषित करते हैं, लेकिन मैं प्रोग्राम के रूप में वर्ग संकलन करना चाहते हैं। मैंने कई अलग-अलग तरीकों की कोशिश की है, लेकिन हर बार मुझे ClassNotFoundException मिलता है क्योंकि क्लास क्लाइंट साइड पर शुरुआत में नहीं है।

Class<?> dateClass = (Class<?>) in.readObject(); //This is where the CNF Exception occurs 
Compiler.compileClass(dateClass); 

उत्तर

7

जावा क्रमबद्धता तंत्र मानता कक्षाएं deserializing JVM के लिए जाना जाता है, यह वर्ग परिभाषाएँ नहीं भेजता। विशेष रूप से, जब आप एक Class वस्तु को क्रमानुसार, आप बाइट कोड उस वर्ग के लिए नहीं भेजते हैं, लेकिन केवल एक विशेष नाम के साथ एक वर्ग के लिए Class वस्तु को देखने के लिए प्राप्त करने वीएम निर्देश दें।

यह भी ध्यान रखें कि Class ऑब्जेक्ट JVM में परिभाषित कक्षा का प्रतिनिधित्व करता है, यानी कक्षा 'बाइटकोड पहले ही लोड हो चुका है। कक्षा को लोड करने के बाद के बाद बाइटकोड उत्पन्न करने के लिए वर्ग को संकलित करने का प्रयास करने में थोड़ा सा समझ नहीं आता है।

तो, हम किसी भी तरह ग्राहक के लिए वर्ग परिभाषा प्राप्त करने की जरूरत है। सबसे आसान तरीका यह है कि क्लाइंट की किसी भी अन्य क्लास की आवश्यकता है (इसे क्लाइंट की जार फ़ाइल में पैक करके, या क्लाइंट प्रोग्राम स्थापित करने के लिए जो भी साधन आप उपयोग करते हैं)। यदि यह संभव नहीं है, तो आप URLClassLoader का उपयोग करके नेटवर्क पर कक्षा परिभाषा लोड कर सकते हैं, या आप धारावाहिक स्ट्रीम के माध्यम से क्लासफ़ाइल भेज सकते हैं, और कक्षा को लोड करने के लिए क्लाइंट का उपयोग ClassLoader.defineClass पर प्राप्त करने पर।

पुनश्च: यह समस्या वर्ग या नाम नहीं है कि क्या की पूरी तरह से indepedent है। निम्न परीक्षण कोड से पता चलता है कि गुमनाम वर्गों की वस्तुओं धारावाहिक जा सकता है और deserialized ठीक (यदि प्राप्त वीएम वर्ग परिभाषा है):

ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
    try (ObjectOutputStream oos = new ObjectOutputStream(baos)) { 
     Serializable payload = new Serializable() { 
      @Override 
      public String toString() { 
       return "hello from the anonymous class"; 
      } 
     }; 
     oos.writeObject(payload); 
     oos.writeObject(payload.getClass()); 
    } 

    try (ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()))) { 
     System.out.println(in.readObject()); 
     System.out.println(in.readObject()); 
    } 
+1

यह nonymising के बारे में सारगर्भित निहायती बकवास की तुलना में कहीं बेहतर जवाब है, हालांकि वह यह है कि एक मजाकिया शब्द। "जेली" और "विंबल" की तरह। तो अगर हम मजाकिया शब्दों पर मतदान कर रहे हैं तो इस जवाब को अब उन वोटों में खींचना चाहिए। – davidfrancis

+0

यही वह है जो मैं मूल रूप से सोच रहा था। नेटवर्क पर कक्षा के लिए फ़ाइल भेजना, फिर इसे वहां होने पर डीआईआर में इंस्टॉल करना। आश्वासन के लिए धन्यवाद: डी – Avogadro

+0

आपको नेटवर्क क्लासलोडर पर एनन क्लास भेजना ठीक होना चाहिए - उदाहरण के लिए आरएमआई क्लासलोडिंग का उपयोग करना – davidfrancis

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