views:

54

answers:

2

I have a GWT app deployed onto our client's machines. As an ongoing development alongside, we have to release new improved versions of the application fron time to time. Everytime we release a new version we often run into the problem where the client's browser has cached the old scripts scriptsand for a while it behaves strangly as the data it is trying to work with is not quite compatible with it. What is the best way to overcome this problem. Currently I have to tell the users to clear their browser's cache for a new release but it would be nice they don't have to do this.

+4  A: 

By default, the bulk of your app should be cached by the browser until a new version of it is generated by your build process.

It might help to understand the GWT bootstrapping model to understand how this works.

The first script your client requests, your-app-name.nocache.js, is not cached, and it does nothing except check the browser's user agent and capabilities, and make a second request for the relevant app JS.

At this point, the script it requests should be cached by the browser if it's been requested before. This is a {indistinguisable-numbers-and-letters}.cache.html file.

When you redeploy your app, the nocache.js file will be executed and ask for a different cache.html file from the server, which will not already be present in the cache, but which will get cached by the browser once it is downloaded.

Are you doing anything unusual with deferred binding, or with caching headers on your server? This might potentially be causing your nocache.js file to get cached after all, which would make it request old cache.htmls from the browser cache.

Jason Hall
Jason, it looks like it is a side effect of your-app-name.nocache.js being cached in the browser. Shahid has to configure his server to cache only *.cache.js and to not cache *.nocache.js. Other than that everything you mentioned should fall in place automatically.
Ashwin Prabhu
A: 

Possible solution depends on the way you are hosting your application. If you are hosting directly from servlet container, then you can use servlet filter like the one described here:

http://seewah.blogspot.com/2009/02/gwt-tips-2-nocachejs-getting-cached-in.html

Here are appropriate filters from tadedon library:

http://code.google.com/p/tadedon/source/browse/tadedon-servlet/src/main/java/com/xemantic/tadedon/servlet/CacheDisablingFilter.java

http://code.google.com/p/tadedon/source/browse/tadedon-servlet/src/main/java/com/xemantic/tadedon/servlet/CacheForcingFilter.java

And here is guice ServletModule which enables them for the whole guice web application:

http://code.google.com/p/tadedon/source/browse/tadedon-gwt/src/main/java/com/xemantic/tadedon/gwt/http/GwtHttpCachingModule.java

If you are using some reverse proxy in front of tomcat it would be even simpler. In case of apache (e.g. mod_proxy, mod_jk), and assuming that all the application resources (html, graphics, java scripts, css, etc.) are put on apache, just set these options in apache configuration:

<Files *.nocache.*>
  ExpiresDefault "access"
</Files>

<Files *.cache.*>
  ExpiresDefault "now plus 1 year"
</Files>

It is described here:

code.google.com/webtoolkit/doc/latest/DevGuideCompilingAndDebugging.html

(please add http in front, I cannot post second link, due to insufficient karma on stackoverflow) :(

in "Perfect Caching" section. Such deployment scenario assumes that only rpc requests should go through reverse proxy to tomcat. If for some reasons all the application context is proxied to tomcat you can still use apache's LocationMatch directive instead of Files directive.

morisil