clonker.de everything but yet nothing

21Aug/110

GWT serialization and cell widgets

Lately I've been busy with writing some GWT-app based on a content management system. In order to display data, it would be best to use Cell-Widgets. If content gets changed in the browser, somewhere a button-widget is added and one can update it with some RPC call. So far so good. Let's look at this small sample:

public class Contact implements IsSerializable{
	private String	name;
	public Contact(){} // default constructor for serialization
	public Contact(String name){
		this.name = name;
	}
}

As our data objects and somewhere else in the client code:

CellList<Contact> cellList = new CellList<Contact>(new AbstractCell<Contact>() {
	@Override
	public void render(Cell.Context context, Contact value, SafeHtmlBuilder sb){
		sb.appendHtmlConstant("<b>" + value.name + "</b>");
	}
});

Now our cellList gets populated with data, no matter in which kind (either directly, or with some kind of data provider).
If we want to gather our data back out of the cell widget, we usually call:

List<Contact> ourData = cellList.getVisibleItems();

No problem yet. But now the data is useless as long as it stays in the client. We need to get it back to the server. How do we do that? Correct: RPC.
This is where the problems begin - if we execute the call it will fail with a serialization exception.

How could this happen? We did everything correctly: Contact implements IsSerializable (the marker interface for gwt-serialization), it even has the required default constructor. So this can't be the problem.
If we have a closer look, we see that cellList returns a list of contacts (of course it does, since it contains more than one contact.. deuh). Lists are serializable, usually. LinkedList, ArrayList - everything we could guess of.
But internally, CellWidgets return their data via

public List<T> getRowDataValues() {
      return Collections.unmodifiableList(rowData);
}

which is NOT serializable. So this is where we have to look for a solution.
My simple approach that actually works: Wrap the returned list into a new (serializable) list, which will cause the internal data-structure to be overwritten. Sample:

List<Contact> ourData = new LinkedList<Contact>(cellList.getVisibleItems());

In a nutshell: Never send the data of cell widgets back to the server directly, as the internally used structures are not serializable.
Cheers!

Filed under: informatics No Comments