Thanks Rob, your email was very helpful, we are just starting next week with some minor implementation on the new architecture, I'll certainly use this as a reference, thanks for sharing.
On Fri, Dec 19, 2008 at 10:56 AM, Rob Walker <r...@ascert.com> wrote: > > > Rob, do you have any material on that? We are looking to use GWT and >> GWT-RPC >> as our web frontends. >> >> >> > I don't have any real docs as such - all our work has been purely > "internal". I can describe a little of how we work though: > > * We use standard Felix, and the Felix Http Service. Although you > can get more advanced Http handling such as filters etc, we prefer > at present to stick only to the standard OSGi Http Service API > * We've found it easiest to bundle everything into a single > "webui.jar" bundle - which includes: > o our handler "GwtServer" (This is the core plumbing - I'll > talk more about this in a moment) > o the standard GWT structure of ./client, and ./server for > compiled GWT packages e.g. > + obj/com/mycompany/myapp/client > + obj/com/mycompany/myapp/server > o the "www" resources that the GWT compiler generates. This is > the most vital stuff - it includes the HTML, generated > Javascript, PNGs, GIFs, CSS. In our case we also build this > to /obj under /resources > + obj/resources/www > o Our manifest is quite simple - since we have all the GWT > stuff in one bundle, we don't need to export any GWT stuff, > and only need to import packages for our external app > services. This is perhaps not the cleanest separation of > concerns, but it is nice and simple and works for us! We > also embed the appropriate gwt-user.jar as an inner JAR for > our GWT bundle, again, for bigger apps this may not be the > cleanest separation but it keeps it simple. So our generated > manifest looks something like this: > > Manifest-Version: 1.0 > Ant-Version: Apache Ant 1.6.5 > Bundle-ClassPath: .,gwt-user.jar > Metadata-Location: metadata.xml > Bundle-Name: OurWebUI > Bundle-ManifestVersion: 2 > Bundle-Activator: com.mycompany.myapp.ServiceActivator > Bundle-Description: Our WebUI using GWT > Import-Package: javax.cryp > to, javax.crypto.spec, javax.imageio, javax.servlet, > javax.servlet.ht > tp, javax.xml.parsers, org.apache.felix.servicebinder, > org.apache.log > 4j, org.osgi.framework, org.osgi.service.http, > org.supercsv.io, org.s > upercsv.prefs, org.w3c.dom > Bundle-SymbolicName: com.mycompany.myapp > > o We don't include any application services in this bundle - > they're external OSGi services wired in as dependencies > using service binder in the normal way (alternatives such as > iPojo would work just as well). > > * We use an interceptor class between the standard GWT servlet > handler and our own - to ensure there are no nasties with context > classloaders, that can be a problem with OSGi. Our servlets all > subclass from the interceptor: > > public class RpcHandlerServlet > extends RemoteServiceServlet > { > ... > > > public RpcHandlerServlet() { } > > /** > * Intercept method to make sure classloader is set before > call is processed > */ > public String processCall(String payload) throws > SerializationException > { > Thread.currentThread().setContextClassLoader( > this.getClass().getClassLoader() ); > return super.processCall(payload); > } > ... > } > > * Now onto the bit that does the work - our "GwtServer". When this > becomes "active" having had it's bindHttp method called, we're > ready to start work. We have a range of GWT-RPC servlets that do > our work - these are standard servlets, that extend the > interceptor class above, and bridge into the OSGi services of our > core app. In the GwtServer we register 2 kinds of aliases > o servlet aliases - these handle the RPC calls e.g. > > srvHttp.registerServlet("/MyApp/MyRpcService", rpcService, > new Hashtable(), myContext); > (obviously in real use you'd make aliases configurable) > > o at least one resource alias - this is key, it resolves > requests for HTML, CSS, JS, GIF etc etc into the bundle > resources under /resource/www (as mentioned above) e.g. > > srvHttp.registerResources("/MyApp", "", new WebAppContext); > > o and now the most important part - our WebAppContext must > "resolve" resource requests from the GWT client into the > resources in our bundle e.g. > > // just needs to match whatever package base/root you declare > for GWT to use > protected String baseUri = "/com.mycompany.myapp.MyApp"; > > private class WebUiContext implements HttpContext > { > public boolean > handleSecurity(HttpServletRequest > request, HttpServletResponse response) > throws IOException > { > return true; > } > > public String getMimeType(String resource) > { > return null; > } > > public URL getResource(String name) > { > if (name.equals("/") || name.length() == 0) > { > name = indexPage; > } > //Not sure why we need this - but under > Jetty6/GWT1.5.2 there > //seems to be a direct call with alias still attached > if (name.startsWith(alias + "/")) > { > name = name.substring(alias.length()); > } > URL retVal = null; > try > { > retVal = > GwtServlet.class.getClassLoader().getResource("resources/www" + > baseUri + name); > } > catch (Exception ge) > { > app.error("Resource get exception: " + ge + " - > " + name); > } > return retVal; > } > } > > * In your GWT XML config - make sure your entry class matches your > baseUri e.g. > > <entry-point class="com.mycompany.myapp.client.MyApp" /> > > I forget why now, but there is an extra ".client" needed as the last > part of the package name which isn't needed in the baseUri for > resolving resources > > * Last bit as I recall, is the URL to use in client GWT code for > your RPC entry points > > instance = (ClientServiceAsync) > GWT.create(ClientService.class); > ServiceDefTarget target = (ServiceDefTarget) instance; > target.setServiceEntryPoint(GWT.getModuleBaseURL() + > "MyRpcService"); > > Note that you just need the name of the RPC handler servlet here - > GWT takes care of the root path wiring > > That's about it for the general stuff - the rest is just variations on the > above - servlets to wire RPC calls into our back end app, and a few > "fancier" contexts for resource handling (e.g. to make it easy to serve up > JNLP embedded apps) > > Have fun - we're very happy how our web app has come out with GWT and > Felix! > > -- Rob > >