RMI NotSerializableException bien que c'est un objet distant
Je suis en train d'écrire un petit RMI en fonction de Chat.
L'idée est la suivante: le Client s'inscrit lui-même sur le Serveur, et chaque fois que le serveur reçoit un message d'un client, il pousse ce message à tous les autres clients.
Mais je reçois un NotSerializableException bien que, l'objet, je suis de passage comme un paramètre d'une méthode implémente l'interface à Distance.
Voici le code:
(La problématique est la partie la this
paramètre dans this.chatServ.registriereClient(this);
(ClientChat mise en Œuvre))
L' (ClientChat)interface:
public interface ChatClient extends Remote
{
}
(ClientChat)Mise En Œuvre:
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();
}
}
}
(ServerChat) Interface
public interface ChatServer extends Remote
{
void registriereClient(ChatClient client) throws RemoteException;
}
(ServerChat) La Mise En Œuvre
public class LobbyChatServerImpl implements ChatServer
{
ArrayList<ChatClient> clientListe = null;
@Override
public void registriereClient(ChatClient client) {
System.out.println("Client registriert");
this.clientListe.add(client);
}
}
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);
}
Serveur:
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();
}
}
Exception:
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
Comme déjà dit, je me demande pourquoi je reçois ce genre d'Exception, bien que ChatClientImpl est déjà à Distance.
Espère que vous pourrez m'aider:)
OriginalL'auteur Graslandpinguin | 2012-06-15
Vous devez vous connecter pour publier un commentaire.
Objets passés en paramètre ou les résultats de méthodes à distance doit être soit:
Serializable (ou Externalizable), ou
Exporté des objets à distance.
Vôtre est ni. Cependant, comme il implémente une interface à Distance clairement souhaité (2).
Les objets qui s'étendent
UnicastRemoteObject
sont automatiquement exportés de la construction. Les objets qui ne doivent être exportés explicitement, viaUnicastRemoteObject.exportObject()
.OriginalL'auteur user207421
Ce que vous pouvez faire est de configurer un objet de rappel. C'est celle qui s'étend UnicastRemoteObject et quand vous passez cela, il devient un rappel.
http://www.cs.swan.ac.uk/~csneal/InternetComputing/RMIChat.html
Distance n'est pas Sérialisable. Vous ne pouvez pas passer d'un objet proxy de cette façon. Même si vous l'avez fait Serializable il serait envoyer un copie de l'objet qui pourrait exister sur le serveur. La copie de l'objet sur le client ne serait pas appelé.
Pour votre "serveur" pour envoyer des messages à votre "client", vous devez créer un service sur le "client" pour en faire un serveur.
Vous pouvez trouver que l'utilisation d'une solution de messagerie tels que JMS est mieux adapté à cette prise. Un serveur JMS a des sujets que vous pouvez publier et s'abonner. Un simple serveur JMS à utiliser est Active MQ.
Vous pouvez, mais l'objet est appelé sera sur le serveur. Vous ne pouvez pas l'avoir appeler le client à partir du serveur de cette façon. Il y a quelques protocoles RPC à l'appui de cette, mais je n'ai pas rememeber qui (je l'ai écrit dans le passé ;). Pour un serveur de chat, Sujets JMS est le moyen le plus simple pour ce faire.
Voir mon edit. Il y a un moyen de le faire avec le RMI.
Il n'a pas à s'étendre
UnicastRemoteObject
: vous pouvez exporter manuellement.OriginalL'auteur Peter Lawrey
Vous ressemble peut-être oublié 'extends UnicastRemoteObject" sur les implémentations d'interface:
et
OriginalL'auteur leon