Tuesday, July 18, 2017

Re: SerializationException when application is modified


We think that this is due to browsers caching the previous (old) code which is no longer aligned with the server code.  We have reviewed all HTTP headers related to caching and all of the are, we think, correctly configured.

The issue is that your users have downloaded your GWT app and are actively using it while you make an update of that app. Because the app is already downloaded it will make requests with different, outdated serialization information. No caching header can help here.

You are correct that you need to detect the server upgrade and then notify the user that a new version of your app is available and finally reload the browser. At work we do the same and it works pretty well. Basically two things can go wrong:

1.) Downloading a split points (GWT.runAsync)
2.) GWT-RPC requests

So in the first case if GWT.runAsync() fails we simply assume the app has been updated and act accordingly. IMHO downloading a split point should never ever fail unless you do not have internet access and get a StatusCodeException with status code 0. So I think the assumption is relatively safe to make.

For the second case (and any other server requests outside of GWT-RPC, e.g. manually requesting a different servlet) we use a HTTP header containing the app version the user has downloaded. That version will be send with every server request, in case of GWT-RPC we use a custom RpcRequestBuilder to add the header. To set a custom RpcRequestBuilder for your GWT-RPC service you need to hard cast the async service to ServiceDefTarget and then call a setter. The app version itself is embedded into the host page, e.g. index.html, which we generate dynamically on the server. We deploy index.template and app.nocache.js and inline app.nocache.js on the server into the template. The template also has some replacement strings for other information, like the app version. The app version itself can be as easy as the hash of the context root on your server, e.g. hash(/app_20170718). A servlet filter can then check the version and send back a HTTP status code to indicate that the app has been updated.

Sadly you can not really use a custom RpcRequestBuilder to catch GWT-RPC exceptions because the response hasn't been deserialized yet. So if you can not use the version approach described above, maybe you can search for "EX" and "com.google.gwt.user.client.rpc.SerializationException" in the response text but that seems like a poor workaround. Ideally you would do some clever refactoring and introduce a base class for all your AsyncCallback, so you have a central place to handle this exception.

-- J.

--
You received this message because you are subscribed to the Google Groups "GWT Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit+unsubscribe@googlegroups.com.
To post to this group, send email to google-web-toolkit@googlegroups.com.
Visit this group at https://groups.google.com/group/google-web-toolkit.
For more options, visit https://groups.google.com/d/optout.

No comments:

Post a Comment