Rob,

Perhaps you should have just created a page on the Wiki for this. :-)

-> richard

Rob Walker 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



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to