When the new version of app is deployed with changes to the model classes (for example adding/removing fields ). Client who has old version running gets com.google.gwt.user.client.rpc.SerializationException with the RPC made with the old client code and this is expected behavior. As a result we expect to see IncompatibleRemoteServiceException on the client side. However we get StatusCodeException.
StatusCodeException is 500 error and we can't customize the client side behavior easily (we don't want to assume every StatusCodeException or 500 error is a new version) . What could we be doing wrong here?
Note: On the server side (log) we get SerializationExcepion obviously since the serialization policy from the old client is no longer valid with the new server. So Why not throwing IncompatibleRemoteServiceException?
Thanks.
Here's my solution facing that issue:
First extend
RemoteServiceServlet
(all your service servlets will extend from this new class, remember this is server code). This is the relevant code in there:and
The private method
sendError()
is basically a customized copy from GWT 500 error code (sorry for the ugly Google indentation)I used
HttpServletResponse.SC_CONFLICT
(409) but you can probably use a clever error code. The message written is not really important.Then in your custom
RpcRequestBuilder
(this is the client code)We use multiple popups, that's one reason for the Navigator class; of course use your own style there to warn the user.
EDIT: What's going on here?
Until GWT 1.3.3
IsSerializable
was the only interface available to mark a class as GWT RPC serializabled. The next version accepted Java standardSerializable
interface for the same purpose, but adding the requirement of a security policy for objects implementing this interface. By default GWT generate a policy for each compilation with a unique hash name. An old client trying to transfer object marked asSerializable
will throw at server side a serialization policy exception that will be received at client side as a generic runtime error.IsSerializable
allows the old clients to still use the new services as long as the signature remains the same. This means that an alternate solution for this question is to mark every object going thru GWT RPC asIsSerializable
. But if for some reason you need your objects not to be referenced to a GWT interface, this is a nice solution for old clients connections.Check GWT's guide for more details regarding the 1.3.3 fallback.