[Spidermonkey] Error deserializing object

Hello,

Im getting this error when the sending a msg to the server:



Serverside:



[xml]SCHWERWIEGEND: Unhandled error, endpoint:NioEndpoint[1, java.nio.channels.SocketChannel[connected local=/127.0.0.1:4244 remote=/127.0.0.1:49159]], context:Envelope[NioEndpoint[1, java.nio.channels.SocketChannel[connected local=/127.0.0.1:4244 remote=/127.0.0.1:49159]], reliable, 43]

java.lang.RuntimeException: Error deserializing object

at com.jme3.network.base.MessageProtocol.createMessage(MessageProtocol.java:185)

at com.jme3.network.base.MessageProtocol.addBuffer(MessageProtocol.java:161)

at com.jme3.network.base.KernelAdapter.createAndDispatch(KernelAdapter.java:217)

at com.jme3.network.base.KernelAdapter.run(KernelAdapter.java:281)

Caused by: com.jme3.network.serializing.SerializerException: Class not found for buffer data.

at com.jme3.network.serializing.Serializer.readClassAndObject(Serializer.java:360)

at com.jme3.network.base.MessageProtocol.createMessage(MessageProtocol.java:181)

… 3 more

01.08.2012 23:17:19 com.jme3.network.kernel.tcp.SelectorKernel$SelectorThread cancel

INFO: Closing endpoint:NioEndpoint[1, java.nio.channels.SocketChannel[connected local=/127.0.0.1:4244 remote=/127.0.0.1:49159]].

01.08.2012 23:17:19 com.jme3.network.base.DefaultServer connectionClosed

INFO: Client closed:Connection[ id=0, reliable=NioEndpoint[1, java.nio.channels.SocketChannel[closed]], fast=UdpEndpoint[1, /127.0.0.1:58302] ].

01.08.2012 23:17:19 com.jme3.network.kernel.udp.UdpKernel closeEndpoint

INFO: Closing endpoint:UdpEndpoint[1, /127.0.0.1:58302].[/xml]



Clientside:



[xml]01.08.2012 23:17:19 com.jme3.network.base.DefaultClient handleError

SCHWERWIEGEND: Termining connection due to unhandled error

com.jme3.network.kernel.ConnectorException: Connector closed.

at com.jme3.network.base.ConnectorAdapter.run(ConnectorAdapter.java:162)[/xml]



The message looks like this:



[java]package xenira.sparkhope.shs.messages;



import com.jme3.network.AbstractMessage;

import com.jme3.network.serializing.Serializable;



@Serializable

public class GMessage extends AbstractMessage{

private long gameID;

private String[] blue;

private String[] red;

public GMessage () {}

public GMessage (long g, String[] r, String[] b) {

gameID = g; red = r; blue = b; }



public long getGameID() {

return gameID;

}



public String[] getBlue() {

return blue;

}



public String[] getRed() {

return red;

}

}[/java]



The message is sent from my first server (in this case the client) to the second server (in this case the server).

I have already a working connection with the first server and the game-client.

Even after serching for a solution in this forum, i couldnt find something i had made wrong -.-



It would be nice, if someone could help me with this problem…



MfG Lasse Sprengel





PS: Sorry for my bad english, but Im german :wink:

The error is saying that the message class is not registered on the receiving end. Make sure you register all message types in all clients and servers before attempting to transfer messages. This is why I recommend a shared class with a static method that all clients+servers can use to register the messages.

2 Likes

Thank you for the fast reply :wink:



Hmmm thats strange, I think i have registerd the message in all of them:



Server (util.class):



[java]public static void setUpSerializer() {

Serializer.registerClasses(GMessage.class);

}[/java]



Server listener:



[java]public Listener(MyGameServer app, Server server) {

this.server = server;

this.app = app;

server.addConnectionListener(this);

server.addMessageListener(this, GMessage.class);

}[/java]



Client (util.class):



[java]public static void setUpSerializer() {

Serializer.registerClasses(LoginMessage.class, HandshakeMessage.class,

RegisterMessage.class, DataMessage.class, SetBnameMessage.class,

LogoutMessage.class, QueueMessage.class, LobbyJoinMessage.class,

GMessage.class);

}[/java]



Client listener:



[java]public Listener(MyGameServer app, Server server) {

this.server = server;

this.app = app;

server.addConnectionListener(this);

server.addMessageListener(this, LoginMessage.class,

HandshakeMessage.class, RegisterMessage.class,

DataMessage.class, SetBnameMessage.class, LogoutMessage.class,

QueueMessage.class, GMessage.class,

LobbyJoinMessage.class);

}[/java]



I realy dont know, whats wrong with it. It would be nice, if someone could help me.



MfG Lasse Sprengel



PS: I am relatively new to Java. I am making stupid mistakes :stuck_out_tongue:

Registration on client and server has to be IDENTICAL. Same order, same classes, all of them.

2 Likes

Thanks, but how to register, when running both, server and client in one aplication (both using diferent messages)?



Do I have to register like this?



[java]public static void setUpSerializer() {

Serializer.registerClasses(LoginMessage.class, HandshakeMessage.class,

RegisterMessage.class, DataMessage.class, SetBnameMessage.class,

LogoutMessage.class, QueueMessage.class, LobbyJoinMessage.class);



Serializer.registerClasses(GMessage.class);

}[/java]



MfG Lasse Sprengel

If they run in one application then you have to call your registering method exactly once.

Easiest way in my opinion: When starting the game, short after main was called, call your method. Then go on starting client or server and client. This way you will call it only once.

2 Likes

Hmmm it still dosn’t work :?



Maybe this image, I created will show my problem even better.



http://i.imgur.com/i4YOL.png



The connection from “Client” to the “Login-Server” (1) works fine, and the “Login-Server” connects to the “Game-Server” (2) successfully but throws the error I had mentioned in my first post when sending / reciving messages.


@pspeed said:
Registration on client and server has to be IDENTICAL. Same order, same classes, all of them.


But doing so would mean to have usless messages on the Servers/Clients.

The connection (3) wasnt testet by me jet.

Sorry if these questions are stupid, but I dont know what to do :?

MfG Lasse Sprengel
But doing so would mean to have usless messages on the Servers/Clients.


I think that this is not the problem. If I imagine the internal working of the system right, than the registering does mean to put an ID and a Class-Objekt into a table and look that up when a message comes in. Nothing really wasteful.

BTW: Be aware that Mojang is currently being sued because an american company holds a patent on using a login server. (Because the american patent system is even more sick than the european)
1 Like

Thanks for the quick response :wink:


@enum said:
I think that this is not the problem. If I imagine the internal working of the system right, than the registering does mean to put an ID and a Class-Objekt into a table and look that up when a message comes in. Nothing really wasteful.


But I would have to coppy all messages into each aplication :/
I don't think that this is the best way but I'll give it a try.

@enum said:BTW: Be aware that Mojang is currently being sued because an american company holds a patent on using a login server. (Because the american patent system is even more sick than the european)


Thanks for the warning ;) But the Login-Server will not be a Login-Server only, it will handle everything whats account related (like leage of legends, when you cklick start after your login the "main" game starts). I hope there are no problems with the server when doing so.

MfG Lasse Sprengel

EDIT:
Its working now! Thank you verry verry much!

You can technically get around this by specifically giving each message its own ID in the “@Serializable” annotation. It’s really easy to screw things up in bizarre ways, though.



[java]@Serializable(id=123)

public class MyMessage…

[/java]



You just have to make sure never to reuse an ID.



Also, personally I wouldn’t use SpiderMonkey for a login server. I think it’s overkill… but I also already know how to write networking (after all, I wrote SpiderMonkey). I guess it’s convenient if you don’t know how to do it with web services or something.

1 Like