I added a container field to show that I could programmatically add a link using an HTML element: someStuffContainer. I also added another field to be filled in by a call to an RPC service for a logout URL: logoutUrlContainer. (Yes, I know now there is a simpler way to do this: GWT/GAE(Java): when combined with GAE, app.yaml / web.xml user authentication and login/logout not really working . I just wanted to see if I could get it to work.) Note that the someStuffContainer was just there to make this a controlled experiment: to separate the programmatic adding of a URL from filling in that URL with a logout link generated on the server side; this will be relevant below.

This all works in the sense that the programmatic HTML shows up and clicking on the logout url logs the user out. (To see this work, you have to open the logout url in another tab; the GWT devmode plugin freaks out if you go to another page; it seems to get into a state where it just keeps complaining that the app needs to be recompiled and you can't out of that state. Further, you have to hit reload for app engine to demand that you log in again; if you are logged out and the client-side is still running, you can just keep using the app unless on the server side you are checking the user is logged in.)

It seems to me that the name of the container field "logoutUrlContainer" should not matter at all. Therefore, before checking in I thought I would clean up the code and rename it to something more general that reflected the fact that I might use that container for a more general User Status widget. So I renamed "logoutUrlContainer" to "userStatusContainer"; I renamed it in the .html and in the client-side Java (compiled to JavaScript). Now instead of working, this line gets a null pointer exception:

RootPanel.get("logoutUrlContainer").add(userStatusHTML);

I'm a rather experienced coder: I was sure to copy and paste so that the strings matched. I checked using the search feature in emacs. I used ant clean to clean the whole project. I used grep to grep for any binary files (such as classfiles) in the whole project that might have been missed by ant clean and somehow still contained the old name. I restarted the server, killed the browser tab containing the app, etc. I did all of this repeatedly. Repeatedly I get the null pointer exception. I think I did all of that over and over again for at least an hour. Note that the entire time the someStuffContainer always worked; somehow RootPanel.get() always found it, while not finding userStatusContainer. Finally, in desperation I just named the container string back again. Immediately it works. I checked in.

What the heck is going on? Is ant clean missing something? Here is my ant clean target, which I extended myself:

Update: I think I know what happened: the javascript was recompiling, but it never occurred to me that the GWT development plugin would allow the page to be cached. Later I changed the welcome file list and the old welcome file was still displaying. Studying the configuration files, I couldn't think of any way that would be possible. Finally I just hit reload and the new file displayed.

Anyway, caching would explain the error reported in this question. I don't know what GWT is doing allowing the page to be cached, especially in devmode. You think after having been a web developer on and off for 15 years I might have thought of that earlier. However I can't imagine how it is possible for people to be so sloppy with caching effects, especially in development frameworks.

1 Answer
1

it seems to get into a state where it just keeps complaining that the app needs to be recompiled and you can't out of that state

This has to do with the fact that you were debugging, so Dev mode overwrote some of the compiled files with updated versions, and when you didn't recompile (and are launching the app not in dev mode), it notices the missing files and stops. If you want to use dev mode, append ?gwt.codesvr=... to the new page's url, and it will run that page in dev mode as well. Or compile the app, and don't use any page with dev mode (loading that module - other modules are fine).

I suspect if you add that suffix to the url, your entire problem will disappear - the NPE you are seeing if the RootPanel.get("some-id") doesn't match the html page is due to RootPanel.get returning null, and add being called on null.