Sunday, October 28, 2012

Adding Guice to the GWT Sample Application

When you work on pre-existing projects most of the time, it's easy to take for granted the effort that can be involved in setting up all of the fancy infrastructure you've become accustomed to. I set up a new GWT application from scratch last week and while adding Guice support to the server side, I wasted some time because I forgot to disable the servlet that the Google Eclipse Plugin "New Project" wizard set up for me in web.xml.

So for fun, I looked on the web and was rather underwhelmed by the instructions for setting up Guice particularly in the GWT context. To help other people (including my future self), I will walk through it here, in a coherent manner in a single place. The following assumes you are starting from the result of the GWT "New Project" wizard (I called my project "GuiceStarter") and want to Guice-enable the GreetingService.

1. Download Guice, copy the .jar files into war/WEB-INF/lib, and add them to the Eclipse Build Path.
2. Create a module in the "server" package as follows:

public class GuiceStarterAppModule extends AbstractModule {
  @Override
  protected void configure() {
    bind(GreetingServiceImpl.class);
  }
}

3. Create the servlet listener config in the "server" package as follows:

public class GuiceServletConfig extends GuiceServletContextListener {

  @Override
  protected Injector getInjector() {
    return Guice.createInjector(new ServletModule() {
      @Override
      protected void configureServlets() {
        serve("/guicestarter/greet").with(GreetingServiceImpl.class);
      }
    }new GuiceStarterAppModule());
  }
}

4. In web.xml, take out the existing and for greetServlet.

5. In web.xml, add the Guice configuration:


<listener>
    <listener-class>com.scottmcmaster365.weatherapp.server.GuiceServletConfig</listener-class>
</listener>

<filter>
    <filter-name>guiceFilter</filter-name>
    <filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>guiceFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

6. Test this by modifying GreetingServiceImpl as follows:

@Singleton
public class GreetingServiceImpl extends RemoteServiceServlet implements
    GreetingService {

  @Inject
  public GreetingServiceImpl() {  // set a breakpoint here
  }
  // etc.

7. Set a breakpoint in the constructor, debug the Web Application, and make sure the breakpoint gets hit.
8. Start using Guice on the server-side as you normally would.

In a future post, I may also add Guice (Gin) to the client-side.

No comments: