Building a GAE+GWT application using the best practices, Part 5

This is the fifth installment of the series “Building a GAE+GWT application using the best practices“.

In the last post of the series, I’ve shown how to setup a client side GIN+MVP project. This post will discuss the actual building of the UI and GWT-RPC web service calls using GWT-Dispatch on the client side.

Use cases

Before we dive into the code, let’s go over again the use cases our little app has.

  • When the UI loads, it should automatically fetch the latest saved rate
  • Also, the table below the latest rate should display the 10 most recent rates stored in the data store
  • The “Refresh” button does the above two steps
  • The “Fetch latest” button fetches the rate from the bank website, store it in the data store, and insert the latest rate in the recent rate table

MVP pattern

For traditional desktop application, there’s the MVC (Model-View-Control) pattern that’s been in existence for over 20 years, since the Smalltalk days. However, the responsibility separation between the view and controller hasn’t been well defined and over the years, people have been arguing about what whether the business logic should be entirely in controller.

With the MVP (Model-View-Presenter) pattern, the view itself doesn’t contain any logic. The presenter manipulates the view according to business logic. Therefore, the pattern is also called “supervising controller” or “passive view”. This brings a huge benefit because now unit tests only have to deal with presenters, and mock out the view through the display interface. With this setup, the presenter unit tests can be run entirely in JVM. Otherwise, the tests need to involve GWT widgets, which can only be tested with GWTTestCase, which takes a lot longer to run.

MainView

Here I’m using the new GWT2 UiBinder feature. UiBinder makes developing UI less boring.

MainView.ui.xml

<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
	xmlns:g="urn:import:com.google.gwt.user.client.ui">
	<ui:style>
		.rateDisplay {
			font-size: x-large;
			font-weight: bolder;
		}
		
		.mainPanel {
			padding: 10px;
		}
	</ui:style>

	<ui:with type="ratechecker.client.bundles.RateCheckerClientBundle"
		field="bundle"></ui:with>
	<g:DecoratorPanel height="200px">
		<g:VerticalPanel styleName="{style.mainPanel}" verticalAlignment="ALIGN_TOP">
			<g:Label>Latest Selling Rate</g:Label>
			<g:Image resource="{bundle.loading}" visible="false"
				ui:field="loading"></g:Image>
			<g:Label ui:field="rateDisplay" styleName="{style.rateDisplay}"></g:Label>
			<g:HorizontalPanel>
				<g:Button ui:field="fetchLatest">Fetch Latest</g:Button>
				<g:Button ui:field="refresh">Refresh</g:Button>
			</g:HorizontalPanel>

			<g:Label>Recent rates</g:Label>
			<g:FlexTable ui:field="rateTable">
			</g:FlexTable>
		</g:VerticalPanel>
	</g:DecoratorPanel>
</ui:UiBinder> 

UiBinder can inter-operate with GWT2 ClientBundle. If you have used GWT1.x’s ImageBundle, ClientBundle is similar to that, except now with ClientBundle, other client resources are able to be bundled such as CSS stylesheet and external text resource.

MainPresenter.Display

The display interface is the only thing presenter knows about the UI, and the presenter operates/manipulates UI only through the display interface.

The display interface can be standalone, but I find it’s much more convenient to have it as an inner interface inside the presenter class.

	public interface Display extends WidgetDisplay {
		HasText getRateDisplayLabel();
		HasClickHandlers getFetchLatest();
		HasClickHandlers getRefresh();

		void setEnabledFetchLatestButton(boolean isEnabled);
		void setShowLoadingCurrentRate(boolean isLoading);
		/**
		 * Add the rate to the recent rate table.
		 * @param rate
		 * 		The {@link Rate} object
		 * @param toHead
		 * 		<code>true</code> - rate is inserted to the beginning of the table
		 * 		<code>false</code> - rate is appended to the end of the table
		 */
		void addToRecentRates(Rate rate, boolean toHead);
		/**
		 * Clear the recent rates table.
		 */
		void clearRecentRates();
	}

Here we use the “characteristic interface” of the UI elements as return type as they can be mocked. For things that cannot be returned as characteristic interfaces (like FlexTable), we provide methods for the presenter to manipulate the state of the UI objects (such as clearRecentRates()).

MainView.java

Now we have the display interface, we can map these interface methods onto our UI.

package ratechecker.client.mvp;

public class MainView extends Composite implements MainPresenter.Display {

	private static MainViewUiBinder uiBinder = GWT
	.create(MainViewUiBinder.class);

	interface MainViewUiBinder extends UiBinder<Widget, MainView> {
	}

	@UiField
	Button refresh;

	@UiField
	Button fetchLatest;

	@UiField
	Label rateDisplay;

	@UiField
	FlexTable rateTable;

	@UiField
	Image loading;

	private final DateTimeFormat _dateTimeFormat;

	@Inject
	public MainView(final DateTimeFormat dateTimeFormat) {
		_dateTimeFormat = dateTimeFormat;
		initWidget(uiBinder.createAndBindUi(this));
	}

	@Override
	public HasClickHandlers getFetchLatest() {
		return fetchLatest;
	}

	@Override
	public Widget asWidget() {
		return this;
	}

	@Override
	public HasText getRateDisplayLabel() {
		return rateDisplay;
	}

	@Override
	public void setEnabledFetchLatestButton(final boolean isEnabled) {
		fetchLatest.setEnabled(isEnabled);
	}

	@Override
	public void addToRecentRates(final Rate rate, final boolean toHead) {
		final int newRowIdx = toHead ? 0 : rateTable.getRowCount();
		rateTable.insertRow(newRowIdx);
		rateTable.setText(newRowIdx, 0, _dateTimeFormat.format(rate.getTimeFetched()));
		rateTable.setText(newRowIdx, 1, String.valueOf(rate.getRate()));
	}

	@Override
	public void clearRecentRates() {
		rateTable.removeAllRows();
	}

	@Override
	public HasClickHandlers getRefresh() {
		return refresh;
	}

	@Override
	public void setShowLoadingCurrentRate(final boolean isLoading) {
		loading.setVisible(isLoading);
		rateDisplay.setVisible(!isLoading);
	}

	@Override public void startProcessing() { }

	@Override public void stopProcessing() { }
}

A lot of this is boilerplate code to satisfy both UiBinder and GWT-presenter.Display interface. Ideally, the VIew shouldn’t do too much, if any at all. Realistically, this is harder to achieve.

MainPresenter

Finally, we can show you the presenter code.


public class MainPresenter extends WidgetPresenter<MainPresenter.Display> {

	private final DispatchAsync _dispatch;

	private final ILog _logger;

	@Inject
	public MainPresenter(final Display display, final EventBus eventBus, final DispatchAsync dispatch, final ILog logger) {
		super(display, eventBus);
		_dispatch = dispatch;
		_logger = logger;
	}

	@Override
	protected void onBind() {
		registerHandler(display.getFetchLatest().addClickHandler(new ClickHandler() {

			@Override
			public void onClick(final ClickEvent event) {
				fetchSellingRate();
			}

		}));

		registerHandler(eventBus.addHandler(RateFetchedEvent.TYPE, new RateFetchedHandler() {

			@Override
			public void onRateFetched(final Rate rate) {
				saveRate(rate);
			}

		}));

		registerHandler(eventBus.addHandler(RateSavedEvent.TYPE, new RateSavedHandler() {

			@Override
			public void onRateSaved(final Rate rate) {
				display.addToRecentRates(rate, true);
			}

		}));

		registerHandler(display.getRefresh().addClickHandler(new ClickHandler() {

			@Override
			public void onClick(final ClickEvent event) {
				getLatestSavedRates();
			}

		}));

		getLatestSavedRates();
	}

	void getLatestSavedRates() {
		display.setShowLoadingCurrentRate(true);

		final GetRates getRates = new GetRates();

		_dispatch.execute(getRates, new AsyncCallback<GetRatesResult>() {

			@Override
			public void onFailure(final Throwable caught) {
				display.setShowLoadingCurrentRate(false);
				_logger.error("Unable to get saved rates: " + caught.getMessage());
			}

			@Override
			public void onSuccess(final GetRatesResult result) {
				display.setShowLoadingCurrentRate(false);
				display.clearRecentRates();

				for (final Rate rate : result.getRates()) {
					display.addToRecentRates(rate, true);
				}

				// Put the latest rate in the box
				if (result.getRates().size() > 0) {
					final Rate latestRate = result.getRates().get(0);
					display.getRateDisplayLabel().setText(String.valueOf(latestRate.getRate()));
				}
			}
		});

	}

	void fetchSellingRate() {
		display.setShowLoadingCurrentRate(true);
		final CheckRate checkRate = new CheckRate(RateType.Selling);
		_dispatch.execute(checkRate, new AsyncCallback<CheckRateResult>() {

			@Override
			public void onFailure(final Throwable caught) {
				display.setShowLoadingCurrentRate(false);
				_logger.error("Unable to fetch rate: " + caught.getMessage());
			}

			@Override
			public void onSuccess(final CheckRateResult result) {
				display.setShowLoadingCurrentRate(false);
				// enable the fetch button
				display.setEnabledFetchLatestButton(true);
				display.getRateDisplayLabel().setText(String.valueOf(result.getRate().getRate()));
				eventBus.fireEvent(new RateFetchedEvent(result.getRate()));
			}

		});

		// disable the fetch button until RPC succeeds
		display.setEnabledFetchLatestButton(false);
	}

	void saveRate(final Rate rate) {
		final SaveRate saveRate = new SaveRate(rate);

		_dispatch.execute(saveRate, new AsyncCallback<SaveRateResult>() {

			@Override
			public void onFailure(final Throwable caught) {
				_logger.error("Unable to save rate: " + caught.getMessage());
			}

			@Override
			public void onSuccess(final SaveRateResult result) {
				eventBus.fireEvent(new RateSavedEvent(rate));
			}

		});

	}

	@Override protected void onPlaceRequest(final PlaceRequest request) { }

	@Override protected void onUnbind() {}

	@Override public void refreshDisplay() {}

	@Override public void revealDisplay() {}

	@Override public Place getPlace() { return null; }
}

In the binding process, the event handlers are attached to the view components. MainPresenter.bind() was explicitly called by AppPresenter.go(). This is a simple application with one presenter. If there are more presenters, AppPresenter needs to manage the state of these sub-presenters: if they’re active, the bind() method is called. If the presenter is no-longer active, the presenter’s unbind() method should be called to un-attach the handlers, so they don’t interfere with the event handlers that are currently in the active presenter.

The presenter is also responsible for making web service calls and deal with the returns. To call GWT-RPC web service using GWT-dispatch, we inject a DispatchAsync, which is an asynchronous counter part of the DispatchServlet introduced a few posts ago.

To call a web service, we simply construct an action object with required parameters and pass it in DispatchAsync.execute() and expect an AsyncCallback of type result that’s coupled with the action. (remember each action has a coupled result type). Also, in this application, every action has a related event to indicate whether the action is successful. The event is thrown onto the event bus, so any interested party can handle that. The main benefit of using event bus is that my web service calls don’t have to be coupled with the subsequent actions. For example, saveRate() method is responsible for making the web service calls, but the subsequent action (adding the saved rate to the recent rate table) isn’t part of saveRate() method, and it shouldn’t be. If in the future, some other actions need to be carried out when a rate is saved, we just have to add the action in the RateSavedHandler, and indeed, if another part of the UI (not visible by main presenter) need to do something after the rate is saved, that presenter only needs to handle that event in there without affecting saveRate() method at all.

For view the full source code, take a look at the project I created on GitHub.

EDIT:For any Google App Engine experts out there happened to be reading this post, I’m having trouble with the performance of this simple app. Seems like the data store is taking way too much time executing my query. Initially I thought it was because URL fetch is slow, but I recently added a property in Rate entity to track the time spent on fetching the URL and every request takes less than 1 second. However, the GetRates action takes a long time to return (usually ~3 to 5 seconds, sometimes even over 10 seconds). It’s a simple query ordering on a single property so no complex index is needed. So I’m wondering what’s wrong here.

Building a GAE+GWT application using the best practices, Part 4

This is the fourth installment of the series “Building a GAE+GWT application using the best practices“.

In the last blog post, we went over how to write GWT-RPC handlers using GWT-dispatch and dependency injection (Guice). This section, we’re going to see how the client side is set up.

Dependencies

We need the following dependencies

They need to be on the classpath when you compile your GWT code, but not under the war directory like the server dependencies need to be.

Module definition

The first step is to declare the inherited GWT modules in the module XML file:
RateChecker.gwt.xml

<?xml version="1.0" encoding="UTF-8"?>
<module rename-to="ratechecker">
    <inherits name="com.google.gwt.user.User" />
    <inherits name="com.google.gwt.inject.Inject" />
    <inherits name="net.customware.gwt.dispatch.Dispatch" />
    <inherits name="net.customware.gwt.presenter.Presenter" />
    <inherits name="com.allen_sauer.gwt.log.gwt-log-DEBUG" />
    <inherits name="com.google.gwt.user.theme.chrome.Chrome"/>

    <entry-point class="ratechecker.client.RateChecker" />

    <source path="client" />
    <source path="shared" />

</module>

Here we specify the explicitly the packages need to be included for compiling – “client” and “shared”. If not specified, GWT will by default compile every source file under the client package.

Create a Gin Module

Gin and Guice implements the same API (or rather, Gin has the same interface as Guice), but Gin uses GWT deferred binding “magic”. Similar to what we have on the server side, on the client side, we start by defining our module:
RateCheckerClientModule:

public class RateCheckerClientModule extends AbstractPresenterModule {

	public RateCheckerClientModule() {
	}

	@Override
	protected void configure() {

		bind(EventBus.class).to(DefaultEventBus.class).in(Singleton.class);
		bind(PlaceManager.class).in(Singleton.class);

	}
}

To start up, we bind EventBus and PlaceManager in the singleton scope. They’re both provided by GWT-mvp library.

AppPresenter

There are different ways to facilitate the MVP pattern but the way I find the most convenient is to have an AppPresenter manage all subsequent presenters. The view the AppPresenter represents is the RootPanel of GWT.

public class AppPresenter {

	private HasWidgets _container;

	private final MainPresenter _mainPresenter;


	@Inject
	public AppPresenter(final MainPresenter mainPresenter) {
		_mainPresenter = mainPresenter;
		_mainPresenter.bind();
	}


	public void go(final HasWidgets container) {
		_container = container;
		_container.clear();
		_container.add(_mainPresenter.getDisplay().asWidget());
	}
}

Here, MainPresenter is the actual UI. The go() method of AppPresenter is for the module entry point to call when the module first initializes. We need to add the bindings to the client module:

        ...
	@Override
	protected void configure() {

		bind(EventBus.class).to(DefaultEventBus.class).in(Singleton.class);
		bind(PlaceManager.class).in(Singleton.class);
		bind(ILog.class).to(GwtLogAdapter.class).in(Singleton.class);
		bind(AppPresenter.class);

		bindPresenter(MainPresenter.class, MainPresenter.Display.class, MainView.class);
	}
        ...

Dependencies

We need the following dependencies

They need to be on the classpath when you compile your GWT code, but not under the war directory like the server dependencies need to be.

Module definition

The first step is to declare the inherited GWT modules in the module XML file:
RateChecker.gwt.xml

<?xml version="1.0" encoding="UTF-8"?>
<module rename-to="ratechecker">
    <inherits name="com.google.gwt.user.User" />
    <inherits name="com.google.gwt.inject.Inject" />
    <inherits name="net.customware.gwt.dispatch.Dispatch" />
    <inherits name="net.customware.gwt.presenter.Presenter" />
    <inherits name="com.allen_sauer.gwt.log.gwt-log-DEBUG" />
    <inherits name="com.google.gwt.user.theme.chrome.Chrome"/>

    <entry-point class="ratechecker.client.RateChecker" />

    <source path="client" />
    <source path="shared" />

</module>

Here we specify the explicitly the packages need to be included for compiling – “client” and “shared”. If not specified, GWT will by default compile every source file under the client package.

Create a Gin Module

Gin and Guice implements the same API (or rather, Gin has the same interface as Guice), but Gin uses GWT deferred binding “magic”. Similar to what we have on the server side, on the client side, we start by defining our module:
RateCheckerClientModule:

public class RateCheckerClientModule extends AbstractPresenterModule {

	public RateCheckerClientModule() {
	}

	@Override
	protected void configure() {

		bind(EventBus.class).to(DefaultEventBus.class).in(Singleton.class);
		bind(PlaceManager.class).in(Singleton.class);

		bind(AppPresenter.class);
		bindPresenter(MainPresenter.class, MainPresenter.Display.class, MainView.class);
	}

We’ll defer the introduction of MainPresenter, MainView and other UI related components to the next post.

Ginjector

Similar to “Injector” interface on the server side, the client side needs to define a Ginjector that act as a gateway for Gin managed object instances.

RateCheckerGinjector.java


@GinModules({RateCheckerClientModule.class, ClientDispatchModule.class})
public interface RateCheckerGinjector extends Ginjector {

	AppPresenter getAppPresenter();

}

Here the annotation @GinModules({…}) makes the instances managed by RateCheckerClientModule and ClientDispatchModule available for the ginjector. ClientDispatchModule binds DispatchAsync interface, which is what we will use to interface with the web service methods.

Entry Point

Finally, here’s the module entry point:

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class RateChecker implements EntryPoint {

	RateCheckerGinjector _injector = GWT.create(RateCheckerGinjector.class);

	@Override
	public void onModuleLoad() {

		final AppPresenter appPresenter = _injector.getAppPresenter();
		appPresenter.go(RootPanel.get("root"));
	}

}

GWT.create(…) statement here creates the ginjector at runtime. Behind the scene, it generates a class (by the name of something like RateCheckerGinjector_Impl) that contains the code to instantiate the bound classes, and when Gin sees a @Inject annotation on a class’s constructor, it provides the instances with the correct scope from the dependency injection container (Ginjector) to the constructor so that the said class can be instantiated.

The onModuleLoad() method doesn’t do much. It simple binds the appPresenter with the RootPanel where the app’s UI is going to be displayed.

I know a lot of the concrete UI creation has been left out of this post, but hopefully it will become clearer once the next post is in.

Building a GAE+GWT application using the best practices, Part 3

This is the third installment of the series “Building a GAE+GWT application using the best practices“.

In this part of the series, we’re going to explore the designing of the web services for RateChecker and coding them using the command pattern from GWT-dispatch based on Ray Ryan’s presentation.

The big picture


To correctly implement web services using the command pattern, we first have to get the big picture. There are three “actors” involved in this: an action, a result and a handler.

Action

An action is used to store the parameters of the web service call (if any). For instance, a CheckRate action needs to know what type of rate the user is checking: buying rate? selling rate? currency?

Result

A result object stores the result (duh…) of the web service call. In the case of CheckRate method, the result is the rate object containing the details of the rate.

Handler

A handler is the actual “worker” that actually does the work of checking the rate. In this case, the check rate method fetches the posted rate page , parses the text (if needed) to get the rate information.

Dispatch and DispatchAsync

A Handler is executed on the server side (by the DispatchServlet we saw in the last post). On the client side, there’s a counterpart “DispatchAsync”, which is the asynchronous interface that the client code calls.

Implementing web service methods

Now that we have the big picture in place, we’re going to look into how to actually implement them.
The first step is to define a domain model. In this case, it’s our Rate class:

@PersistenceCapable(identityType=IdentityType.APPLICATION)
public class Rate implements Serializable {

	private static final long serialVersionUID = -4415279469780082174L;

	@PrimaryKey
	@Persistent(valueStrategy=IdGeneratorStrategy.IDENTITY)
	private Long id;

	@Persistent
	private RateType type;

	@Persistent
	private Date timeFetched;

	@Persistent
	private Double rate;

	public Rate() {
	}
        // ... getters and setters omitted
}
public enum RateType {
	Selling,
	Buying,
}

In our example application, we are going to define three simple web methods:

  • Check rate: use Url fetch to get the posted rate page and return a rate object from that.
  • Save rate: persist the rate object into the data store.
  • Get rate: get the rates from the data store.

Check rate

As we have shown in the big picture, every action needs three pieces: action, result (both in shared package, as they will be used by both the client and the server) and the handler (lives in the server package).

For CheckRate action, we need to specify the type of rate it needs to check. For simplicity, I’m always dealing with USD/CAD rate. The parameter here is only for whether to check for buying rate or selling rate.

public class CheckRate implements Action<CheckRateResult> {

	private static final long serialVersionUID = -1716760883016361503L;

	private RateType _type;

	public CheckRate() {
	}

	public CheckRate(final RateType type) {
		_type = type;
	}

	public void setType(final RateType type) {
		_type = type;
	}

	public RateType getType() {
		return _type;
	}

}

The result is designed to hold the returned Rate object.

public class CheckRateResult implements Result {

	private static final long serialVersionUID = -9099789297842581458L;

	private Rate _rate;

	public CheckRateResult() {
	}

	public CheckRateResult(final Rate rate) {
		_rate = rate;
	}

	public void setRate(final Rate rate) {
		_rate = rate;
	}

	public Rate getRate() {
		return _rate;
	}
}

Word of caution: because both action and result are serialized and sent over the wire as part of GWT-RPC call, they are required to have a default public constructor.

Now, on to the handler:

public class CheckRateHandler implements ActionHandler<CheckRate, CheckRateResult> {

	public static final String URL_BUY = "http://www.ingdirect.ca/en/datafiles/rates/usbuying.html";

	public static final String URL_SELL = "http://www.ingdirect.ca/en/datafiles/rates/usselling.html";

	public CheckRateHandler() {
	}

	@Override
	public CheckRateResult execute(final CheckRate action, final ExecutionContext ctx) throws ActionException {
		final CheckRateResult retval = new CheckRateResult();

		String strUrl = null;
		switch (action.getType()) {
		case Buying:
			strUrl = URL_BUY;
			break;
		case Selling:
			strUrl = URL_SELL;
			break;
		}

		try {
			final URL url = new URL(strUrl);

			BufferedReader br = null;
			try {
				br = new BufferedReader(new InputStreamReader(url.openStream()));

				final double dRate = Double.parseDouble(br.readLine());

				final Rate rate = new Rate();
				rate.setRate(dRate);
				rate.setType(action.getType());
				rate.setTimeFetched(new Date());

				retval.setRate(rate);

			} finally {
				if (br != null)
					br.close();
			}
		} catch (final MalformedURLException e) {
			e.printStackTrace();
			throw new ActionException(e);
		} catch (final IOException e) {
			e.printStackTrace();
			throw new ActionException(e);
		} catch (final NumberFormatException e) {
			e.printStackTrace();
			throw new ActionException(e);
		}

		return retval;
	}
        // ... other methods omitted
}

As you can see, the handler does the actual work of fetching the rate using URL Fetch service offered by Google App Engine.

The other two web method implementations are similar. You can follow the project on Github here. In the next section, I’m going to go over the building of the UI in GWT, as well as making AJAX calls from GWT to the server.

Building a GAE+GWT application using the best practices, Part 2

This is the second installment of the series “Building a GAE+GWT application using the best practices“.

In Part 2, we’re going to go over project setup for GAE and GWT applications, and wire the server (servlet) using Guice and GWT-Dispatch.

Project setup

I’m using Eclipse as my development environment. Install Google Eclipse plugin, and install the provided GWT (2.0.2) and GAE (1.3.1) with the plugin. Create a new project in Eclipse using the “New web application project” wizard, and create a sample project.

Now, because during deployment, GAE applications are executed within its own servlet container, all dependencies have to be placed inside the directory /war/WEB-INF/lib. Go ahead, download Guice, GWT-dispatch, GWT-log, commons-logging and log4j. Put the jar files inside /war/WEB-INF/lib directory. Then in Eclipse, select the jars you just placed, right click and select “Add to build path”. Your lib directory should look something like this:

“Wiring” the server

Now that the project is setup, we need to wire the server to utilize the dependency injection container Guice. The details can be found here but in short, we need to do the following:

Modify web.xml

Find web.xml in /war/WEB-INF. In traditional GWT-RPC development, every service needs to be written as a servlet and declared in web.xml. For Guice + GWT-dispatch, we only need a filter and a listener (as the entry point).

<webapp>
        [...]
	<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>

	<listener>
		<listener-class>ratechecker.server.guice.GuiceServletConfig</listener-class>
	</listener>
        [...]
</webapp>

Here, our listener is ratechecker.server.guice.GuiceServletConfig. It reads like the following

public class GuiceServletConfig extends GuiceServletContextListener {

	private ServletContext _ctx;

	@Override
	public void contextDestroyed(final ServletContextEvent servletContextEvent) {
		_ctx = null;
		super.contextDestroyed(servletContextEvent);
	}

	@Override
	public void contextInitialized(final ServletContextEvent servletContextEvent) {
		_ctx = servletContextEvent.getServletContext();
		super.contextInitialized(servletContextEvent);
	}

	@Override
	protected Injector getInjector() {
		return Guice.createInjector(new GuiceServerModule(), new DispatchServletModule());
	}

}

This code is borrowed from Hupa. The responsibility of this servlet context listener is to construct an injector (achieved by the last method). Here, our injector contains two modules, ratechecker.server.guice.GuiceServerModule and ratechecker.server.guice.DispatchServletModule.

DispatchServletModule

public class DispatchServletModule extends ServletModule {
	@Override
	protected void configureServlets() {
		super.configureServlets();
		serve("/ratechecker/dispatch").with(RateCheckerDispatchServlet.class);
	}
}

This module has a mapping of URIs and its serving classes. It serves “/ratechecker/dispatch” with RateCheckerDispatchServlet, which is the entry point for GWT-dispatch.

GuiceServerModule

public class GuiceServerModule extends ActionHandlerModule {

	public GuiceServerModule() {
	}

	@Override
	protected void configureHandlers() {
            // declare bindings
	}

}

This is where you declare your bindings for the application. We’ll come back to this file frequently as the application develops.

RateCheckerDispatchServlet

@Singleton
public class RateCheckerDispatchServlet extends DispatchServiceServlet {

	private static final long serialVersionUID = 4895255235709260169L;

	private final Log _logger;

	@Inject
	public RateCheckerDispatchServlet(final Dispatch dispatch, final Log logger) {
		super(dispatch);
		_logger = logger;
	}

	@Override
	public Result execute(final Action<?> action) throws ActionException {
		try {
			_logger.info("executing: " + action.getClass().getName());
			final Result res = super.execute(action);
			_logger.info("finished: " + action.getClass().getName());
			return res;
		} catch (final ActionException ae) {
			_logger.error(ae.getMessage());
			ae.printStackTrace();
			throw ae;
		} catch (final Exception e) {
			_logger.error("Unexpected exception: " + e.getMessage());
			e.printStackTrace();
		}
		return null;
	}
}

This servlet extends from GWT-dispatch’s DispatchServiceServlet. It’s main responsibility is to provide unified logging.

Notice you cannot run the application, because Guice is complaining that there’s no binding for org.apache.commons.logging.Log, which we declared as a dependency for RateCheckerDispatchServlet. We go ahead write our LogProvider (to provide lazy initialization for the Log object to its users)

LogProvider

public class LogProvider implements Provider<Log> {

	@Override
	public Log get() {
		return new Log4JLogger("RateCheckerLogger");
	}

}

Now the binding should be added to GuiceServerModule:

[...]
	@Override
	protected void configureHandlers() {
            bind(Log.class).toProvider(LogProvider.class).in(Singleton.class);
	}
[...]

Now everytime Guice sees Log.class declared as a dependency in the constructor, it uses LogProvider.get() method to retrieve an instance of the log if there’s none, and uses the existing log instance if it’s been initialized (because of the singleton scope).

In the end, your server package should look like this:

We haven’t covered PersistenceManagerProvider but it’s the same idea as LogProvider. It provides an instance of PersistenceManager, which is used by the data store related action handlers to deal with data persistence.

That’s it for server wiring. In the next blog post, I’ll go through designing and writing GWT-RPC services using Guice and GWT-dispatch.

Building a GAE+GWT application using the best practices, Part 1

This is the first installment of the series “Building a GAE+GWT application using the best practices“.

Introduction

In the next few blog posts, I’m going to present my experience building a simple (but non-trivial) web application using GWT and Google App Engine, while applying the best practices introduced by Ray Ryan in his excellent presentation at Google IO last year.

The application I’m going to build is called RateChecker. It’s simply a tool that goes fetches the posted USD/CAD exchange rate from a bank website, persists the rate to the data store, and present the user with the recent rates when requested. It can potentially do more (like generating a histogram of the rates, etc), but for the purpose of blog series, I’m going with the basics to illustrate the implementation pattern without losing my bearings in the embellishing.

Here’s a screenshot of the finished application:

The Goals

I intend to use this minimal application to practice using the following technologies/techniques:

  • Server/Persistence tier:
    • Google Guice as dependency injection container on the server side
    • JDO as the persistence layer
    • AppEngine Cron task
    • Command pattern for request handling
  • Client tier:
    • Google GIN as dependency injection container on the client side
    • Model-View-Presenter pattern on the client side
    • EventBus to decouple components
    • Command pattern for remote service calls
  • Unit Testing on both Client/Server side with mock objects

Also I plan to rewrite the service layer with one of the alternate JVM language, such as Scala or Clojure, if I my schedule allows and I have enough motivation.

GXT Widget Expander 1.0 release

This project aims to add flexibility to GXT row expander by enabling putting arbitrary widgets in the expanded row.

GXT’s grid widget is great, especially with the RowExpander plugin, it allows the creation of a Google Reader style grid (a list with expandable rows). However, the current GXT’s RowExpander design only allows rendering by XTemplate. XTemplate falls short in a number of ways, especially when it comes to user interaction inside the expanded rows.

Using the WidgetExpander, you’ll write something similar to the following

    WidgetExpander<SomeModel> expander = new WidgetExpander<SomeModel>(new WidgetRowRenderer<SomeModel>() {

        public Widget render(final SomeModel model, final int rowIdx) {
            // Create and return a widget according to the model
        }
    });

    // Add expander into a list of ColumnConfigs
    // Create a grid with the ColumnConfig list
    grid.addGridPlugin(expander);

With this enhancement, we’re now able to do this:

Check it out here on Github: http://github.com/kevinjqiu/gxt-widget-expander

Setting up GWT2 project with gwt-maven-plugin

GWT2 offers a lot of exciting new features: OOPHM, SOYC, code splitting, declarative UI, to name a few. This evening, I experimented setting up a GWT2 project using Codehaus’s gwt-maven-plugin.

I’m using Eclipse, so obviously, you need m2eclipse and Google Eclipse Plugin. First step is creating a Maven project:
File->New->Project…->Maven Project

In the archetype selection dialog, select org.codehaus.mojo.gwt-maven-plugin:1.1.

We choose this to create an archetype but 1.1 doesn’t work with GWT2. Later on, we will modify pom.xml to use another version of the plugin.

Enter your project’s GroupId, ArtifactId, Version, and Package -> Finish

The plugin generates an archetype of GWT 1.6 project. In Eclipse, open pom.xml. As stated earlier, gwt-maven-plugin 1.1 doesn’t work with GWT2. You need 1.2, but since 1.2 hasn’t been released, we will use the snapshot version. The snapshot version is hosted on codehaus’s snapshot repository, so we need to add the repository first.

Id: codehaus-snapshot-repository
Name: (anything you like)
URL: http://snapshots.repository.codehaus.org

Then, change the version of gwt-maven-plugin from 1.1 to 1.2-SNAPSHOT

Also, you need to specify the module and runTarget in the configuration of the plugin, something similar to the following:

		<plugins>
			<plugin>
				<groupId>org.codehaus.mojo</groupId>
				<artifactId>gwt-maven-plugin</artifactId>
				<version>1.2-SNAPSHOT</version>
				<executions>
					<execution>
						<goals>
							<goal>compile</goal>
						</goals>
					</execution>
				</executions>
				<configuration>
					<module>com.mycomp.demo.mygwt2.Application</module>
					<runTarget>com.mycomp.demo.mygwt2.Application/Application.html</runTarget>
				</configuration>
			</plugin>
  </plugins>

Save the pom. Eclipse will be busy fetching the dependencies and building the project.

After it’s done, it’s time to create launchers.

Right click on pom.xml, Run As->Maven Build…, in the Run Configurations dialog, put “gwt:compile gwt:run” as the goals.

Hit “run”, GWT Development Mode application will appear.

The final missing piece is the debug mode. One of the advantages of using GWT is developing AJAX application with existing Java tooling. So let’s go ahead and set it up.
Right click on pom.xml->Run As->Maven build…
In the following dialog, enter “gwt:debug” as goals, save it.

Click on the dropdown of the debug button on the toolbar, select “Debug Configurations”.
In the left panel, find “Remote Java Application”, select it and click the icon for “New launch configuration” (top left corner). Accept defaults, save, and close.

Put a breakpoint at Application.onModuleLoad(), start the debug server by running the debug launcher we just created. (the one with goal gwt:debug). When you see “Listening for transport dt_socket at address: 8000” in the console output, run the attach launcher we just created (the remote debugger). The GWT Development Mode app pops up. Because GWT2 uses OOPHM (Out Of Process Hosted Mode), you need to copy the start URL and paste it in a browser (I’m using FF). If it’s the first time you run hosted mode like that, you will be asked to install a Firefox plugin. After it’s installed, paste the URL into the address bar. If everything goes well, your breakpoint will be hit.

There you have it. A sample mavenized GWT2 project. Enjoy the goodies offered by both GWT2 and Maven!

Solving a GWT deferred binding mystery

This morning at work, I was running our GWT application with some deferred binding logic in it, and all of a sudden I got this ridiculous message:

[ERROR] Class 'mycompany.rebind.HistoryResourceGenerator' must derive from 'com.google.gwt.core.ext.Generator'
[ERROR] Failure while parsing XML
com.google.gwt.core.ext.UnableToCompleteException: (see previous log entries)
at com.google.gwt.dev.cfg.ModuleDefSchema$ObjAttrCvt.convertToArg(ModuleDefSchema.java:729)
at com.google.gwt.dev.util.xml.HandlerArgs.convertToArg(HandlerArgs.java:64)
at com.google.gwt.dev.util.xml.HandlerMethod.invokeBegin(HandlerMethod.java:214)
at com.google.gwt.dev.util.xml.ReflectiveParser$Impl.startElement(ReflectiveParser.java:257)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:501)

It was running fine yesterday when I left work, and now it tells me that my generator isn’t a subclass of the GWT Generator??? Quickly pulled the source, and it’s as clear as day that my generator is properly written. Then what gives?

Searching for an explanation, I pulled the GWT’s source code, and opened com.google.gwt.dev.cfg.ModuleDefSchema and here’s the method in question:

    public Object convertToArg(Schema schema, int lineNumber, String elemName,
        String attrName, String attrValue) throws UnableToCompleteException {

      Object found = singletonsByName.get(attrValue);
      if (found != null) {
        // Found in the cache.
        //
        return found;
      }

      Class<?> foundClass = null;
      try {
        // Load the class.
        //
        ClassLoader cl = Thread.currentThread().getContextClassLoader();
        foundClass = cl.loadClass(attrValue);
        Class<? extends T> clazz = foundClass.asSubclass(fReqdSuperclass);

        T object = clazz.newInstance();
        singletonsByName.put(attrValue, object);
        return object;
      } catch (ClassCastException e) {
        Messages.INVALID_CLASS_DERIVATION.log(logger, foundClass,
            fReqdSuperclass, null);
        throw new UnableToCompleteException();
      } catch (ClassNotFoundException e) {
        Messages.UNABLE_TO_LOAD_CLASS.log(logger, attrValue, e);
        throw new UnableToCompleteException();
      } catch (InstantiationException e) {
        Messages.UNABLE_TO_CREATE_OBJECT.log(logger, attrValue, e);
        throw new UnableToCompleteException();
      } catch (IllegalAccessException e) {
        Messages.UNABLE_TO_CREATE_OBJECT.log(logger, attrValue, e);
        throw new UnableToCompleteException();
      }
    }
  }

Because the error message was from Messages.INVALID_CLASS_DERIVATION, I put a breakpoint on line 22:

Messages.INVALID_CLASS_DERIVATION.log(logger, foundClass, fReqdSuperclass, null);

and started my app in debug mode. The breakpoint hits, and I noticed that the exception object is reporting ClassCastException from JSONNull to JSONObject. I quickly clicked: The error is from the class that fetches some resource over the net and plugged in to the generator. Following this lead, I found that the server resource the class was fetching wasn’t available any more, which caused the fetcher class to fail, and consequently, the ClassCastException is propagated to the generator and eventually ModuleDefSchema.

The mysterious error message, however, has nothing to do with the real problem. I spent a lot of time thinking that my Generator is wrong, because that’s what the compiler says, but in fact, it’s not. I think the confusion can be avoided if the GWT compiler can log the actual exception object, instead of interpreting the exception for the user. That’s what they’re doing in the try/catch clause in the method shown above: the exception object “e” is not used in the case of ClassCastException…

Well, the take-home message is: don’t always trust the GWT compiler message. Also, adding log more logging to your generator classes that can be indicative to where the actual problem is.

Integrating SmartGWT with ASP.NET JSON web service

Many web API authors are using third party libraries like JayRock to convert ASP.NET web service method return values to JSON.  ASP.NET does have the ability to return JSON objects for web methods.  It’s not a very well-known feature (I guess) as there are only a few places mentioning it. http://encosia.com/2008/03/27/using-jquery-to-consume-aspnet-json-web-services/ 

For example, suppose the web method we are calling is /ItemService.asmx/GetList, and it’s expecting a parameter “uid”. For JSON web service to work, we have to set the request content type to “application/json” and provide the request parameter as a JSON object and send it through HTTP POST data ({uid:’12345′}).

In the current project I’m working on, I’m hooking up SmartGWT’s Data source to use JSON web service of ASP.NET. SmartGWT’s data source allows OperationBinding to be set for each of the four CRUD operations. For ItemDS, my fetch operation looks like the following:

    OperationBinding createFetchOperation() {

        final OperationBinding retval = new OperationBinding(DSOperationType.FETCH, Urls.ISSUE_FETCH);
        retval.setDataFormat(DSDataFormat.JSON);

        retval.setDataProtocol(DSProtocol.POSTPARAMS);

        retval.setRecordXPath("/result");

        return retval;

    }

Since we’re doing a bunch of customized stuff, we’re bound to override transformRequest() method in the DataSource class:

class ItemDS extends RestDataSource {
    /* data source setup */
    @Override
    protected void transformRequest(DSRequest req) {
        // TODO
    }
}

We need to do two things in transformRequest:
1) set request header to “application/json; charset=utf-8”
2) set the request payload to be the JSON object that contains parameters to the web service
So here we go:

/* inside transformRequest() */
dsRequest.setContentType("application/json; charset=utf-8");
final JavaScriptObject params = JSOHelper.createObject();
JSOHelper.setAttribute(params, "uid", "12345");
req.setData(params);
return req.getData();

Does that work? A simple test proved that it didn’t. Because remember we set data protocol on the fetch operation to “POSTPARAMS”? It turns out that even though req.data is sent via POST body, it’s URL form-encoded, not JSON encoded as you would expect since we already set data format to JSON. A bit digging on the SmartGWT forum turned out that data format setting only affects the parsing of the return value, not the outbound parameters.

Okay…let me try again…This time, I’m setting DSProtocol to POSTMESSAGE, as this seems to be a more logical choice (as the parameters are going to be sent out as POST message/body). Does it work? I wish…From the DevConsole, it turns out that SmartGWT’s RPC Manager sends out “[Object]” in POST body…Whaaat? Looking at SmartGWT’s API, it doesn’t allow setting request data as a simple string. It has to be a JavaScriptObject instance. I digged inside SmartGWT’s source code, setting the attribute ‘data’ directly to the JSON object that I want to use, but GWT shell complains it cannot cast from java.lang.String to JavaScriptObject…Sighhhh

It starts to get frustrating. This evening, as I was going through some JavaScript stuff, it dawns to me that the notion “[Object]” seems to be the string representation of a generic JavaScript object. (i.e., the return of an object’s toString() method). Looking at JavaScriptObject class in GWT confirms this. So, what if I just override toString() method and just return a JSON object?

This is like an epiphany! I went over some articles on how to do GWT JSNI and quickly come up with this:

    /* Modify OperationBinding, set to use POSTMESSAGE protocol */
    setDataProtocol(DSProtocol.POSTPARAMS);

    /* in ItemDS */
    static native void setValue(JavaScriptObject jso, String val) /*-{
        jso.toString = function() {
            return val;
        }
    }-*/;
    /* in transformRequest */
    /* ... setup content type ... */
    final JavaScriptObject data = JSOHelper.createObject();
    setValue(data, "{uid:'12345'}");
    req.setData(data);
    return data;

A voila!!! The DevConsole shows that RPC manager sends out {uid:12345} as the HTTP POST data and I got right what I want.