I'm facing the issue of how to reconstruct data across a network in Java. As part of my Component based game engine (read about it here, I have to encode components as XML on the server, send it to the client, and then reconstruct the appropriate component with all the data included in the XML. For example:

Right now, I use reflection on the client to construct a new TextureComponent (but this will work for any component with primitive data types) using the complete name of the class. I then sequentially read all the String parameters from the XML into the component using reflection in this BasicDecoder:

Is there any way I can improve this code? Is reflection the wrong way to go? I shied away from having each Component define its own decoder because I felt that it would result in a lot of classes which look more or less similar.

2 Answers
2

Reflection is not the correct way to do this. You will need Serialization for this. Another option is to use XML marshalling and unmarshalling, but I am not so familiar with that.

For serialization I suggest you to pick up a copy of Effective Java, and read the last couple of items of the book, which are all about Serialization.

You really need to take care of the following, since you are dealing with a game and network:

Check your class invariants, constructors may not violate them.

Make sure that your seriliazation is all safe as attackers can exploit a lot of things to do some quite surprising things.

Take care of the evolvability of your classes, serialization does pose some issues on that.

I would recommend all your classes to implement a static inner classes called ProxyHelper and implement the Proxy Serialization Pattern on the classes.

Some other ad-hoc review points of your current code:

Do not catch Exception, catch the subclass(es) that you actually see happening, currently it will also catch RuntimeExceptions.

Do preferably not throw RuntimeException, but add somewhat more detail, IllegalStateException may be a candidate here.

Follow the coding conventions, you do it quite well in general, but in the switch (type) { } every case (and inherited code lines) need to be indented one more factor.

In general I would never let Reflection do such a task, I would add with the following code, either a public constructor taking all arguments of the object (which you can get from the String[] data), or if there are too many arguments (more than five usually), you can also emply the Builder Pattern.