Ich schreibe eine kleine RMI-basierte Chat-Anwendung.RMI NotSerializableException obwohl es ein Remote-Objekt ist
Die Idee ist: der Client registriert sich auf dem Server, und jedes Mal, wenn der Server eine Nachricht von einem Client erhält, schiebt er diese Nachricht an alle anderen Clients.
Aber ich erhalte eine NotSerializableException, obwohl das Objekt, das ich als Methodenparameter übergebe, die Remote-Schnittstelle implementiert. Hier
ist ein Code: (Der problematische Teil ist der this
Parameter in this.chatServ.registriereClient(this);
(ClientChat Implementation))
Die (ClientChat) Schnittstelle:
public interface ChatClient extends Remote
{
}
(ClientChat) Umsetzung:
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) Schnittstelle
public interface ChatServer extends Remote
{
void registriereClient(ChatClient client) throws RemoteException;
}
(ServerChat) Umsetzung
public class LobbyChatServerImpl implements ChatServer
{
ArrayList<ChatClient> clientListe = null;
@Override
public void registriereClient(ChatClient client) {
System.out.println("Client registriert");
this.clientListe.add(client);
}
}
Auftraggeber:
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);
}
Server:
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();
}
}
Ausnahme:
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
Wie bereits erwähnt, frage ich mich, warum ich diese Art von Ausnahme bekomme, obwohl ChatClientImpl bereits Remote ist.
Hoffe Ihr könnt mir helfen :)
wie man es in Client- und Server-Klassen getrennt verwendet? – Usman
@Usman Wie benutzt man was? – EJP