2012-06-15 15 views
9

है मैं एक छोटा आरएमआई आधारित चैट आवेदन लिख रहा हूँ।आरएमआई NotSerializableException हालांकि यह एक दूरस्थ वस्तु

विचार यह है कि: क्लाइंट सर्वर पर खुद को पंजीकृत करता है, और जब भी सर्वर क्लाइंट से संदेश प्राप्त करता है, तो वह इस संदेश को अन्य सभी ग्राहकों को धक्का देता है।

लेकिन मुझे एक NotSerializableException प्राप्त होता है हालांकि, ऑब्जेक्ट, मैं एक विधि पैरामीटर के रूप में गुजर रहा हूं दूरस्थ इंटरफ़ेस लागू करता है। (समस्याग्रस्त हिस्सा this.chatServ.registriereClient(this); में this पैरामीटर है (ClientChat कार्यान्वयन))

(ClientChat) इंटरफेस:

public interface ChatClient extends Remote 
{ 

} 

(ClientChat) कार्यान्वयन:

यहाँ कुछ कोड है

public class ChatClientImpl implements ChatClient 
{ 

    ChatServer chatServ; 
    String clientName; 

    public ChatClientImpl(String clientName, ChatServer chatServ) { 
     this.chatServ = chatServ; 
     this.clientName = clientName; 
     try { 
      this.chatServ.registriereClient(this); 
     } catch (RemoteException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

(सर्वरकैट) इंटरफेस

public interface ChatServer extends Remote 
{ 
     void registriereClient(ChatClient client) throws RemoteException; 

} 

(ServerChat) कार्यान्वयन

public class LobbyChatServerImpl implements ChatServer 
{ 

    ArrayList<ChatClient> clientListe = null; 

    @Override 
    public void registriereClient(ChatClient client) { 
     System.out.println("Client registriert"); 
     this.clientListe.add(client); 
    } 
} 

ग्राहक:

public static void main(String[] args) { 
     ChatServer lobbyChatServer = null; 
     try { 
      Registry registry = LocateRegistry.getRegistry(Server.RMI_PORT); 
      lobbyChatServer = (ChatServer) registry.lookup("LobbyChatServer"); 

     } catch (RemoteException e) { 
      e.printStackTrace(); 
     } catch (NotBoundException e) { 
      e.printStackTrace(); 
     } 

     ChatClient lobbyChat = new ChatClientImpl(name, lobbyChatServer); 
    } 

सर्वर:

public static void main(String[] args) { 
     try { 
      if (System.getSecurityManager() == null) { 
       System.setSecurityManager(new RMISecurityManager()); 
      } 

      Registry registry = LocateRegistry.getRegistry(RMI_PORT); 

      ChatServer lobbyChatStub = (ChatServer)UnicastRemoteObject.exportObject(new LobbyChatServerImpl(), 0); 
      registry.bind("LobbyChatServer", lobbyChatStub); 

     } catch (RemoteException e) { 
      e.printStackTrace(); 
     } catch (AlreadyBoundException e) { 
      e.printStackTrace(); 
     } 
    } 

अपवाद:

java.rmi.MarshalException: error marshalling arguments; nested exception is: 
    java.io.NotSerializableException: de.XX.Chat.ChatClientImpl 
    at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:156) 
    at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:194) 
    at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:148) 
    at $Proxy0.registriereClient(Unknown Source) 
    at de.XX.Chat.ChatClientImpl.<init>(ChatClientImpl.java:19) 
    at de.XX.Client.main(Client.java:49) 
Caused by: java.io.NotSerializableException: de.XX.Chat.ChatClientImpl 
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1180) 
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:346) 
    at sun.rmi.server.UnicastRef.marshalValue(UnicastRef.java:292) 
    at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:151) 
    ... 5 more 

जैसा कि पहले से ही कहा गया है, मुझे आश्चर्य है कि मुझे इस तरह की अपवाद क्यों मिलती है, हालांकि ChatClientImpl पहले ही रिमोट है।

आशा है कि आप मेरी मदद कर सकते :)

उत्तर

14

वस्तुओं मानकों या दूरदराज के तरीकों के परिणाम के रूप में पारित किया जाना चाहिए या तो:

  1. Serializable (या Externalizable), या

  2. निर्यात दूरस्थ वस्तुओं।

आपका न तो है। हालांकि यह एक रिमोट इंटरफेस लागू करता है स्पष्ट रूप से आप इरादा (2)। UnicastRemoteObject का विस्तार करने वाले ऑब्जेक्ट्स निर्माण पर स्वतः निर्यात किए जाते हैं। ऑब्जेक्ट्स जिन्हें UnicastRemoteObject.exportObject() के माध्यम से स्पष्ट रूप से निर्यात नहीं किया जाना चाहिए।

+0

क्लाइंट और सर्वर कक्षाओं में अलग-अलग इसका उपयोग कैसे करें? – Usman

+0

@ उस्मान कैसे उपयोग करें? – EJP

1

आप क्या कर सकते सेटअप एक कॉलबैक वस्तु है। यह वह है जो UnicastRemoteObject को बढ़ाता है और जब आप इसे पास करते हैं तो यह कॉलबैक बन जाता है।

http://www.cs.swan.ac.uk/~csneal/InternetComputing/RMIChat.html


Remote Serializable नहीं है। आप इस तरह प्रॉक्सी ऑब्जेक्ट पास नहीं कर सकते हैं। यहां तक ​​कि यदि आपने इसे Serializable बनाया है तो यह सर्वर पर मौजूद ऑब्जेक्ट के प्रति कॉपी करेगा। ग्राहक पर वस्तु की प्रतिलिपि नहीं कहा जाएगा।

अपने "सर्वर" के लिए अपने "क्लाइंट" को संदेश भेजने के लिए आपको इसे "क्लाइंट" पर एक सर्वर बनाने के लिए एक सेवा बनाना है।

आप पाएंगे कि जेएसएमएस जैसे मैसेजिंग समाधान का उपयोग करना इस ले के लिए बेहतर है। एक जेएमएस सर्वर में ऐसे विषय होते हैं जिन्हें आप प्रकाशित और सदस्यता ले सकते हैं। उपयोग करने के लिए एक सरल जेएमएस सर्वर सक्रिय एमक्यू है।

+0

इसलिए, अगर मैं आप सही समझते हैं, मैं एक के माध्यम से एक दूरस्थ वस्तु पारित नहीं हो सकता सर्वर के लिए पैरामीटर और सर्वर को इस पारित वस्तु पर अन्य विधियों को कॉल करने दें? – Graslandpinguin

+0

आप कर सकते हैं, लेकिन ऑब्जेक्ट कहा जाता है सर्वर पर होगा। आप इस तरह से सर्वर से क्लाइंट को कॉल नहीं कर सकते हैं। कुछ आरपीसी प्रोटोकॉल हैं जो इसका समर्थन करते हैं, लेकिन मुझे याद नहीं है कि (मैंने अतीत में एक लिखा है;)। चैट सर्वर के लिए, जेएमएस टॉपिक्स ऐसा करने का सबसे आसान तरीका है। –

+0

मेरा संपादन देखें। आरएमआई के साथ करने का एक तरीका है। –

-1

सुनिश्चित करें कि सर्वर पैकेज नाम क्लाइंट के साथ मिलते हैं, अन्यथा, मार्शलएक्सप्शन ऑब्जेक्ट को आरएमआई रजिस्ट्री से कॉल करने पर फेंक दिया जा सकता है।

यह वास्तव में एक सीधी चीज है लेकिन आपको खुशी हो सकती है। मुझे उम्मीद है कि आपको यह काम का लगेगा।

+0

प्रश्न का उत्तर नहीं देता है। इसे एक टिप्पणी के रूप में पोस्ट किया जाना चाहिए था। – EJP

1

ऐसा लगता है कि करना भूल गए हैं इंटरफेस कार्यान्वयन पर 'UnicastRemoteObject फैली':

public class ChatClientImpl extends UnicastRemoteObject implements ChatClient{ 
} 

और

public class LobbyChatServerImpl extends UnicastRemoteObject implements ChatServer{ 
} 
संबंधित मुद्दे