Wednesday, July 27, 2011

Writing GWT Linker for offline applications – issues

I was very surprised by the number of users visiting my last post regarding the GWT Linker which allows you to compile application manifest for offline support. There are also some issues reported, thank you very much about the feedbacks.

Now I will try to keep it short, there is issue when you compile your application using the linker from my post HERE and then you run the application and open it, you will realize that the generated manifest file is empty. This happens because of a small bug in the linker.

The linker checks if the SelectionInformation is empty and if this is the case sets the ArtifacSet to null. The problem then is that I call after that every time the function emitLandingPageCacheManifest, but because the artifact is null it generates empty manifest which overrides the one you compile.

Now I made a small fix, I am not sure if this is the best way to do it, but fix the issue for now. The fix I made was in the link() function, so that the function now looks like this:

1 @Override
2 public ArtifactSet link(TreeLogger logger, LinkerContext context,
3 ArtifactSet artifacts, boolean onePermutation)
4 throws UnableToCompleteException {
5 ArtifactSet toReturn = new ArtifactSet(artifacts);
7 if (onePermutation) {
8 return toReturn;
9 }
11 if (toReturn.find(SelectionInformation.class).isEmpty()) {
12 logger.log(TreeLogger.INFO, "Warning: Clobbering " + MANIFEST
13 + " to allow debugging. "
14 + "Recompile before deploying your app!");
15 artifacts = null;
16 } else {
17 // Create the general cache-manifest resource for the landing page:
18 toReturn.add(emitLandingPageCacheManifest(context, logger,
19 artifacts));
20 }
21 return toReturn;
23 };

You can get the latest code from HERE.

I hope that helps, if you have any other issues do not hesitate to post them!



  1. Hi - thanks for your fix - it works.
    I had simply put the following on top of the link method:

    if (artifacts.find(SelectionInformation.class).isEmpty()) return toReturn;

    Moreover, I added config properties as another way to specify static output, as in

    <extend-configuration-property name="cache.staticfiles" value="/Mobile.jsp"/>

    Simply because I like that more than subclassing the linker. Alas I wasn't able to figure out how to access the file system from the linker in order to implement wildcards as in

    <extend-configuration-property name="cache.staticfiles" value="/images/*" />

    Maybe you know?

  2. This is also very nice approach, I would try it as well. Regarding your question, I am not sure, which will be the best approach, but normally in the linker you have access to the content of all files before there are saved to the file system, so I would prefer to do the changes there and then when you return the artifacts, the changes will be saved to the file system.

  3. Hi, would it work for a GWT application that requires storage. e.g. GWT and hibernate application?

    1. I am not sure what you mean, can you give me a use case?