Reputation: 707
I have a serializable object with a TreeMap.
Map<String, Dogs> dogsByNames = Maps.newTreeMap(); // guava style
So far, everything is fine. Now it's nessassary to ignore the case of the keys:
Map<String, Dogs> dogsByNames = Maps.newTreeMap(String.CASE_INSENSITIVE_ORDER);
This do not work because String.CASE_INSENSITIVE_ORDER isn't serialzable:
com.google.gwt.user.client.rpc.SerializationException: Type 'java.lang.String$CaseInsensitiveComparator' was not included in the set of types which can be serialized by this SerializationPolicy or its Class object could not be loaded. For security purposes, this type will not be serialized.: instance = java.lang.String$CaseInsensitiveComparator@f26f68
So I create my own one:
private static abstract class MyComparator<T>
implements
Comparator<T>, // extends Ordering<T> do not work
IsSerializable { // Serializable do not work
}
public static final MyComparator<String> CASE_INSENSITIVE_ORDER = new MyComparator<String>() {
@Override
public int compare(final String left, final String right) {
if (null == left) {
return (null == right) ? 0 : -1;
} else if (null == right) {
return 1;
}
return left.compareToIgnoreCase(right);
}
};
But this still do not work.
Whats wrong?
Solution:
protected static class MyOrdering // no-private!!!
extends
Ordering<String>
implements
IsSerializable {
@Override
public int compare(final String left, final String right) {
if (null == left) {
return (null == right) ? 0 : -1;
} else if (null == right) {
return 1;
}
return left.compareToIgnoreCase(right);
}
}
public static final Ordering<String> CASE_INSENSITIVE_ORDER = new MyOrdering();
Upvotes: 4
Views: 1855
Reputation: 166
The CASE_INSENSITIVE_ORDER you created is an anonymous class, which cannot be serialized in GWT. To make it GWT serializable, you need to
Create a custom top-level class (like
CaseInsensitiveOrder implements Comparator<..>, Serializable {
...
}
Create a constant CASE_INSENSITIVE_ORDER
like you did.
CaseInsensitiveOrder_CustomFieldSerializer
), which returns the CASE_INSENSITIVE_ORDER
instance on deserialize()
.Upvotes: 5
Reputation: 12692
A stacktrace of the error would be helpful. But I'll hazard the guess that you get an exception like:
com.google.gwt.user.client.rpc.SerializationException: Type 'com.foo.Bar.MyComparator' was not included in the set of types which can be serialized by this SerializationPolicy or its Class object could not be loaded. For security purposes, this type will not be serialized
This happens because GWT creates a list of all the types it might need to serialize, at compile-time. This is the "serialization policy". To do so, GWT inspects all your RPC methods for arguments and return types, and searches for all the "reachable" types.
The compiler might not realize that your Comparator will be serialized, and it is not added to the serialization policy.
A workaround is to declare a dummy method, which takes as parameter all the types that might need to be serialized, as described in this other SO answer. Something like:
// in your RPC interface
SerializationWhitelist dummyMethodForSerializationPolicy(SerializationWhitelist serializationWhiteList);
// the SerializableWhiteList class
public class SerializationWhitelist {
public Bar.MyComparator<String> myComparator;
}
Upvotes: 0