Need Help Serializing Array

Hi,

I’m pretty new to JMonkeyEngine, and even newer to SpiderMonkey (i started today). I ran into a problem and tried to solve it for hours, but i dont seem to make any progress:



Im trying to send an Object with Client.send() and i get an exception saying:



Sep 29, 2010 1:02:51 AM com.jme3.network.serializing.serializers.FieldSerializer writeObject

WARNING: [FieldSerializer][???] Exception occured on writing. Maybe you’ve forgotten to register a class, or maybe a class member does not have a serializer.

Sep 29, 2010 1:02:51 AM bomberdude.server.Game notifyPlayerClients

SEVERE: null

java.io.IOException: java.lang.NullPointerException

at com.jme3.network.serializing.serializers.FieldSerializer.writeObject(FieldSerializer.java:110)

at com.jme3.network.serializing.Serializer.writeClassAndObject(Serializer.java:241)

at com.jme3.network.connection.TCPConnection.send(TCPConnection.java:200)

at com.jme3.network.connection.TCPConnection.sendObject(TCPConnection.java:184)

at com.jme3.network.connection.Client.send(Client.java:189)

at bomberdude.server.Game.notifyPlayerClients(Game.java:77)

at bomberdude.server.Game.(Game.java:54)

at bomberdude.server.ServerController.clientConnected(ServerController.java:63)

at com.jme3.network.connection.ClientManager.fireClientConnected(ClientManager.java:130)

at com.jme3.network.connection.ClientManager.messageReceived(ClientManager.java:88)

at com.jme3.network.connection.Connection.fireMessageReceived(Connection.java:307)

at com.jme3.network.connection.TCPConnection.read(TCPConnection.java:150)

at com.jme3.network.connection.Connection.run(Connection.java:92)

at com.jme3.network.connection.ConnectionRunnable.run(ConnectionRunnable.java:47)

at java.lang.Thread.run(Thread.java:636)



That problem only occurs, when my object contains an array. I tried different variations of registering an ArraySerializer with that array, but i cant figure out, how to do it. can anyone help and tell me how to do this?



This is, what the array in the object currently looks like:

@Serializable(serializer=ArraySerializer.class)

private PlayerState[] playerStates = new PlayerState[4];



And i try to register the “class” like this:

Serializer.registerClass(PlayerState[].class,new ArraySerializer());



But its obvisously wrong. The rest of the sending/serialization is working well while i dont have that array in my object.



I hope someone can tell me how to do this right.

Manuel

Addition:

i can also serialize as long as that field is only a single variable and not an array

Once you have the @Serializable annotation, you need to use Serializer.register(myclass.class); without the [] :slight_smile:



Sorry for the short message, posting from phone:)

Thanks for your answer.

I finally figured it out: The Problem was, that the fields of the Array had not all been initialized. I constructed the array like

FieldType[][] map = new FieldType[20][20];

And when i tried to serialize this, i got that error i posted below.

But the exception gets thrown, when FieldSerializer tries to compute this piece of code:



public void writeObject(ByteBuffer buffer, Object object) throws IOException {



SavedField[] fields = savedFields.get(object.getClass());



And when “object” in this case is null, i get a nullpointerexception. The exception which is afterwards thrown is somehow misleading:



“Maybe you’ve forgotten to register a class, or maybe a class member does not have a serializer.”



Maybe you could change this into some more userfriendly error-output.

I was very confused, because i was sure i registered the serializer correctly (simply FieldSerializer on my “root-class”) and all field-objects have the @Serializable()-annotation…

The only problem were the uninitalized array-members.



I am thankful for your work, nice api!

btw: Are you the developer of spidermonkey? If that’s the case, do you mind me posting the issues i have while i use it?

One thing i found is, that its possible to register Enums with a serializer (which doesnt throw an exception or cause the Serializer to complain in any way), and its possible to send objects that way (i guess), but on clientside, when i receive those enums, i get an InstantiationException. I solved that by not registering those Enums to the Serializer. Maybe it would be better not even to allow registration, so developers would see directly where that problem arises.

I hope my critics are ok,

Manuel

I’ll look into the writeObject() issue and error handling, thanks!



Yes I am the dev of SpiderMonkey.



Of course it’s okay that you post the issues, I’ll even be very grateful, so please do! Thanks alot!!



I’ll look into the Enum problem - I don’t really get what you mean right now, but I’m sure that’ll arise once I write a test case for it, thanks!

mbaum said:
public void writeObject(ByteBuffer buffer, Object object) throws IOException {

SavedField[] fields = savedFields.get(object.getClass());

And when "object" in this case is null, i get a nullpointerexception. The exception which is afterwards thrown is somehow misleading:

"Maybe you’ve forgotten to register a class, or maybe a class member does not have a serializer."

A null object shouldn't throw an exception anymore in latest alpha. I've tested and tried to reproduce the situation nonetheless, and came up with nothing but good messages and no exceptions. Let me know if any other problems occur.


mbaum said:
One thing i found is, that its possible to register Enums with a serializer (which doesnt throw an exception or cause the Serializer to complain in any way), and its possible to send objects that way (i guess)


In the latest alpha, you have to use send(), which does not allow Objects anymore, only Messages. This means this problem got 'accidentally' fixed. Enums can still be part of other messages, though! As long as you register them.