I am using Google Web Toolkit and Java Google App Engine to write an app. I have found a situation where the following happens very predictably. I have a servlet the app.yaml entry for which looks like this:
handlers: - url: /foo/* name: FooServlet servlet: com.waga.server.FooServlet login: required
This servlet checks that the user is logged in (redundant, I know), looks for the user in the database, and if found includes a Bar.jsp file to render an HTML page that includes javascript to load a GWT module. This Bar.jsp file and GWT module have been working for a while, with only a few minor recent changes to allow the servlet to check things before rending the Bar.jsp and with some code added to the top of the Bar.jsp file to compute a few strings to include into the page.
I put a log.info at the top of the servlet, at the top of the Bar.jsp file, and at the bottom of the Bar.jsp file. When I use GWT devmode to go to the servlet, I see the log messsages in the following order:
Foo servlet top Bar.jsp top Bar.jsp bottom Foo servlet top Foo servlet top Bar.jsp top Bar.jsp bottom Bar.jsp top Bar.jsp bottom
That is, the servlet seems to be being visited by the browser 3 times, and not synchronously (note that the last two overlap). This is happens every time I run it.
Further, the Bar.jsp file says it is rendering the page, but the GWT javascript never loads and renders the client-side app. It has in the past, so that should work; that is, the GWT client-side code was working and I have just been rearranging how the urls map to servlet and how the servlets include the .jsp files. Further, when devmode is compiling the Java to JavaScript on the server before sending it to the client, my laptop fan comes on and I can see Java using most of my CPU for quite a few seconds in order to do this; I do not see that now.
I tried getting rid of the Servlet and just having the app.yaml call the .jsp directly (everything that the Servlet checks I happen to know passes, such as me already being logged in, so it does nothing.) That is, I tried making the app.yaml say this:
handlers: - url: /foo/* jsp: Bar.jsp login: required
Now the log says this
Bar.jsp top Bar.jsp botton Bar.jsp top Bar.jsp top Bar.jsp bottom Bar.jsp bottom
Same interleaving and same symptoms that the GWT module never seems to be loaded.
Advertisement
Answer
This situation becomes more obvious when I print out the request.getPathInfo() at the top of the Bar.jsp file. The problem was that I trusted GWT webAppCreator to generate reasonable code when I started the project and I did not think about my URL paths carefully. In particular, webAppCreator generates HTML that refers to the compiled javascript client from the web page as follows:
<!-- --> <!-- This script loads your compiled module. --> <!-- If you add any GWT meta tags, they must --> <!-- be added before this line. --> <!-- --> <script type="text/javascript" language="javascript" src="waga/waga.nocache.js"></script>
Note the relative path in the src URL, instead of an absolute path. In my opinion generating an absolute path makes a lot more sense as they don’t accidentally move the target around in the filesystem if you, say, map a URL with a prefix to this .jsp file, which is exactly what I did; in particular the path to the generated javascript client makes no sense as a relative path as the compiler is always going to put it into a specific place in the filesystem. Making the path (as well as another relative path to a .css file I had also used) absolute by prepending a slash fixed the problem.