Google Web Toolkit and Equinox
My team has been interested for some time in exposing web-based interfaces to some of the capabilities wrapped up in our RCP plugins. At EclipseCon I attended the tutorial offered by the Google Web Toolkit (GWT) team and I thought "Gee, wouldn't it be neat if you could put a GWT-based interface on a servlet running in an Equinox http server?" As it turns out, it is neat, and here's a rough description of how to do it:
First, I downloaded the Equinox Jetty server plugins as discussed here:
Note that you have to use the Jetty stuff because org.eclipse.equinox.http doesn't support Servlet 2.4, which appears to be required by GWT.
Next, I wrapped up gwt-user.jar and gwt-dev-windows.jar in a plugin that I called com.google.gwt. One critical point here - the jars include javax.servlet, which is also included with Equinox. These classes conflict and cause a nasty classloader error. In order to avoid this, you just have to *not* export the javax.servlet packages from this new GWT plugin. Many thanks to Pascal of the Eclipse platform team for helping me to track this problem down in between sessions at EclipseCon!
Armed with Equinox and GWT, I made an example plugin containing a basic application that the GWT team presented at EclipseCon, called Chattr. In that plugin I extended the extension points provided by Equinox to register both the static html resources and the Chattr servlet, as shown below:
<?xml version="1.0" encoding="UTF-8"?> <?eclipse version="3.2"?> <plugin> <extension point="org.eclipse.equinox.http.registry.resources"> <resource alias="/" base-name="/www"/> </extension> <extension point="org.eclipse.equinox.http.registry.servlets"> <servlet alias="/org.eclipsecon.gwt.chattr.Chattr/chattr" class="org.eclipsecon.gwt.chattr.server.ChatServiceImpl"/> </extension> </plugin>
Finally, since GWT uses reflection to deserialize the classes passed to and from the servlet, the GWT plugin needs to be able to access the classes in the example plugin described above. Since the example plugin already depends on the GWT plugin, we can't create a direct dependency in the opposite direction. So, I used buddy classloading. In the GWT plugin, I put this:
In the example plugin, I put this:
Finally, I created an Equinox OSGI Framework run configuration, added my example plugin and all required plugins, and started it up. Pointing Firefox at the OSGI http port shows that everything is working fine. I confirmed that I could access classes in another plugin from my example plugin.
Of course, this doesn't allow for the magic of GWT self-hosting, but I think it's a great start.