Get GWT working in WebSphere with details

I had to deploy a GWT application (2.x) based on GWT-platform into IBM WebSphere (6.1 and 7) and that was not piece-of-cake at all. It has been tested on JBoss (4.x) first without any issue. So what is wrong with WebSphere (or GWT) ?

Available information in forums sounds more like magic than engineering: one thread about Guice, another about GWT Dispatch.

As I am not satisfied when something falls into function [hum, my favorite expression in french: "tomber en marche"] without deep understanding, I have investigated why GWT/Guice does not work out-of-the-box on WebSphere and how it should work.

  • First, WebSphere does not trigger your Guice ServletContextListener at application initialization without additional Web Container Custom Properties. Here it is:
    com.ibm.ws.webcontainer.invokeFiltersCompatibility = true
    from WebSphere v7 InfoCenter
  • Second, WebSphere only triggers the listener at first request on a Servlet only, but not for resources like generated GWT html/javascript content. With a GWT application, you get the initial content from a JSP and then a RPC call to /dispatch. I have not checked if the ServletContextListener is already called because of the request to the JSP, which is a specific kind of Servlet. The call just fails with 404, as if the listener has not been triggered.
  • Conclusion part 1: even if your application does not require any JavaEE Servlet, you have to register one, with the option load-on-startup to enforce the listener to be really called at application deployment.

But it is not enough. When a new servlet mapping is added with the Servlet API, WebSphere does not honor it. It still answers 404 about /dispatch.

So the fake servlet you have to use to initiate the context and trigger the listener at application deployment MUST be mapped to /dispatch to reserve the servlet mapping in WebSphere. Then the DispatchServletModule will replace the fake servlet by the real DispatchServiceImpl when invoking the method serve on /dispatch.

Next trouble: the gwtapplication.jsp page is registered as a welcome file list in web.xml. So when you use /myappcontext/ in your browser, you get the gwtapplication.jsp content. Great it works ! Until a RPC call to a SecuredAction is invoked. It fails with a security failure because of the lack of the security cookie at client side. Why ? The Guice filter is not invoked, the pattern *.jsp has not been matched. To ease diagnostic, the DispatchService answers a blank page with status code 200. Thank you guys for the non-ending wait progress in the browser, why not return a 403 status ? Here is the bug report.

Now how to get WebSphere to behaves like others, I mean Tomcat the reference implementation ? Just add the following custom property to the Web Container:
com.ibm.ws.webcontainer.mapFiltersToAsterisk = true

In case of doubt or failure, just directly browse /myappcontext/gwtapplication.jsp to get your security cookie set.

Here I am. All that work to get a GWT/Guice/gwt-platform application just work in WebSphere. Hope it may save you some hours.

Bonus: during my tests, I have made a mistake in servlet name reference for servlet-mapping tag. Guess what: you just get a NullPointerException in SystemOut with any obvious cause in stack trace. The IBM guy has forgotten to handle human failure in its web.xml configuration parsing ! I would expect a clean error message like the servlet name « foobar » referred in servlet-mapping at line X is unknown. It may help.

Laisser un commentaire