Hydro4GE — a PaaS built with GWT

Posted by Fred Sauer, Developer Advocate - Wednesday, September 02, 2009 at 5:41:00 PM


From time to time we like to share experiences from fellow developers with you. It's a pleasure to present you today with this guest blog post by Geoff Speicher, Chief System Architect of Hydro4GE.


Hydro4GE (pronounced hy-dro-forge) is a Platform-as-a-Service (PaaS) for building online database applications. Building a powerful tool for developers itself requires a powerful toolkit to meet developers' expectations of a development environment: a highly-interactive, rich user interface (UI) with emerging features such as database schema visualization via interactive, scalable graphics. This article describes our experience in using GWT to rewrite our old HTML+AJAX UI to deliver all of these features with a polished look and solid performance.

Building the UI

When we set out to rewrite the UI using GWT, a quick inventory of available widgets was in order. Our initial reaction was similar to what some others have expressed: that the native GWT widget library did not have quite the same breadth or flair as some third-party libraries such as ExtJS or SmartGWT. However, experimentation with these libraries proved that they are also fairly heavy in weight, and noticeably impacted the application's performance both in its initial download and its interactive responsiveness.
The reason is simple: these generic JavaScript libraries, though highly optimized, are still just that — generic. It is unrealistic for these libraries to achieve the same level of efficiency as code that is produced by the GWT compiler. For this reason, we wanted to avoid the use of external JavaScript libraries when possible.
After some careful consideration and a more detailed analysis of our needs, we discovered that we only needed a small handful of widgets that GWT didn't already provide, and all but one of those (covered in the next section) were easily built using Composite. There is already an excellent blog entry for building Composites, so we will not cover that topic here. The visual styling of both the native and Composite widgets was easy to customize thanks to GWT's liberal and logical use of CSS classnames.
As a quick demonstration, it's pretty impressive what a difference you can achieve by building a few simple Composite widgets and tweaking some of the default styles. Compare the default styling of an input form with one modified by a few simple customizations:

GWT Default Styles & Widgets
Customized for Hydro4GE
If you have not already jumped on the bandwagon, Firefox+Firebug is an indispensable tool for inspecting HTML and tweaking CSS. Thanks to this and the flexibility of the GWT library, we were able to achieve the polished look that we wanted without much work and without sacrificing performance.

Building a Widget from an External Library

What about the one widget that we couldn't build using Composite? We want to use vector graphics to generate scalable diagrams depicting database structure and user interaction for systems you build with Hydro4GE. There are a small handful of vector graphics libraries out there for GWT, but all of them require concessions that we are not willing or able to make. The Google Web Toolkit Incubator's GWTCanvas does not support text rendering (due to a limitation of HTML canvas), and although projects such as abstractcanvas attempt to overcome this limitation, text cannot be rotated and precisely scaled.
In this section, we will show you how to integrate with Raphael, a lightweight JavaScript library for cross-platform vector graphics. Raphael side-steps the HTML canvas issue by using SVG on supported platforms, and Microsoft VML on Internet Explorer. Raphael does everything we need to build our diagrams, except for one thing: integrate directly with our GWT code.
We achieved this integration through two levels of abstraction: (1) a JavaScript Overlay Type to provide a zero-overhead interface to the underlying JavaScript API, and (2) a GWT Widget to wrap the overlay with a more Java-friendly API, resulting in a first-class Widget that will operate side-by-side with native GWT Widgets. Let's have a look at the details for this two-part implementation, starting with the Overlay class.

The Overlay

The RaphaelJS class is nearly an exact replica of the underlying Raphael API. This is made necessary by the restrictions that GWT enforces on JavaScriptObject types, so the implementation is fairly uncreative: one method per Raphael method. Many of these methods appear in the nested class Shape, which represents the type returned by most of the native Raphael methods. The basic idea for the class is:
class RaphaelJS extends JavaScriptObject {
  protected static class Shape extends JavaScriptObject {
    public final native Shape rotate(double degree, boolean abs) /*-{
      return this.rotate(degree, abs);
    public final native Shape scale(double sx, double sy) /*-{
      return this.scale(sx, sy);
    public final native Shape translate(double dx, double dy) /*-{
      return this.translate(dx, dy);
    // ...

   * factory method
  static public final native RaphaelJS create(Element e,
      int w, int h) /*-{
    return $wnd.Raphael(e, w, h);

  public final native Element node() /*-{
    return this.node;

  public final native Shape circle(double x, double y, double r) /*-{
    return this.circle(x,y,r);

  public final native Shape rect(double x, double y,
      double w, double h) /*-{
    return this.rect(x, y, w, h);

  // ...

The Widget

The Overlay bridges the gap between GWT and Javacript, but the Widget is what truly makes the library useful to our application. Since the Widget does not have the restrictions of the JavaScriptObject Overlay, we have the freedom to define our own API as an adaptor to the Overlay.
public class Raphael extends Widget {
  private RaphaelJS overlay;

  public class Shape extends Widget {
    protected RaphaelJS.Shape rs;
    protected Shape(RaphaelJS.Shape s) {
      rs = s;
    public Shape rotate(double degree, boolean isAbsolute) {
      rs.rotate(degree, isAbsolute);
      return this;
    public Shape scale(double sx, double sy) {
      rs.scale(sx, sy);
      return this;
    public Shape translate(double dx, double dy) {
      rs.translate(dx, dy);
      return this;
    // ...

  public class Circle extends Shape {
    public Circle(double x, double y, double r) {
      super(overlay.circle(x, y, r));

  public class Rectangle extends Shape {
    public Rectangle(double x, double y, double w, double h) {
      super(overlay.rect(x, y, w, h));
    public Rectangle(double x, double y, double w, double h, double r) {
      super(overlay.rect(x, y, w, h, r));

  public class Text extends Shape {
    public Text(double x, double y, String str) {
      super(overlay.text(x, y, str));

  // ...

  public Raphael(int width, int height) {
    Element raphaelDiv = DOM.createDiv();
    overlay = RaphaelJS.create(raphaelDiv, width, height);
This implementation defines separate classes that represent the different types of objects (Circle, Text, Rectangle) developers can append to a drawing. A possible alternative implementation might simply expose the underlying JavaScript API as a native GWT widget — in the end, you can write an API that suits your needs.
We chose this implementation because it allows us to implement scalable drawings through inheritance, resulting in custom classes that can be instantiated and appended to any Panel. For example, to create a fullscreen drawing that contains a single, centered circle of radius 20:
public class MyDrawing extends Raphael {
  public MyDrawing(int width, int height) {
    super(width, height);
    Circle c = new Circle(width/2, height/2, 20);
    // Raphael automatically appends the Circle to this drawing

public class MyApp implements EntryPoint {
  public void onModuleLoad() {
    MyDrawing d = new MyDrawing(Window.getClientWidth(),
This is a trivial example, but it clearly demonstrates the simplicity that can be achieved by integrating an external JavaScript library as a Widget. To the consumers of this library, there is no difference between using it (a third-party Javascript library) and the native GWT widget library. That's a powerful statement, and a testament to the GWT design team.

Communicating with the server

With the UI visually complete, it was time to move on to integration with the backend. Our existing backend was implemented in PHP, and we did not want to rewrite it in Java just to support GWT-RPC. Without native support for GWT-RPC calls to a PHP backend, we needed a flexible and efficient communication framework to accomplish the equivalent task. We chose JSON for its simplicity and solid support in both GWT and PHP, but ultimately we learned that regardless of the efficiency of the encoding, it's still easy to make design mistakes that will lead to inefficient communications.
First, we need to get the client and server talking to each other. Making JSON-encoded client requests from GWT is made trivial by using the RequestBuilder class in conjunction with JSONObject, and handling JSON on the server with PHP is easily accomplished using Zend Framework, which provides the Zend_Json class for encoding/decoding JSON, and Zend_Controller for handling and routing requests. This provides the framework we need to tie into our PHP code running on the server.
Having addressed the encoding and handling of requests, our attention turned to dealing with the size and frequency of requests. The whole point of making AJAX requests was to transfer little bits of data instead of re-sending an entire HTML document, but we found a break-even point where the payload became so small that the request frequency was the limiting factor. At one point, we had gotten so carried away breaking up information into atomic pieces that the overhead of each request was exceeding 90% of the total time to complete the request, leaving less than 10% of the time to actually process and transfer the payload.
The reason this can happen is pretty straightforward. Over any network connection, there is a minimum amount of time necessary for the HTTP request/response to live its lifecycle. This is compounded by the two-connection browser limit plus overhead imposed by the network stack and connection latency. The net effect of all this is that if you dispatch one hundred requests in rapid succession, each of which contains only a few hundred bytes of payload data, it would take nearly one hundred times as long to complete all one hundred requests as it would take to transfer the entire payload (tens of kilobytes) in one request. In terms of real-world figures, this translates to a 300 or 400 millisecond time for completion, as opposed to 30 or 40 seconds!
This lesson reminds us that when you write software, you must always design for the limitations of the platform, even when you have great tools at your disposal. In this case, to write efficient web software with GWT, you need to make every HTTP request reach its fullest potential by maximizing its effects.
We achieved this by modeling each request as a collection of atomic commands. In this simple model, each command can return a set of data, and is associated with one or more response data handlers. The commands are processed on the server within a database transaction so that the entire request either succeeds or fails as a single unit without leaving the database in an inconsistent state.
This abstraction allows us to queue up many physical database operations into one logical JSON request, not only improving performance but also allowing us to handle the results in a modular way that involves less code than a typical GWT request callback. In this sense we have actually managed to reduce the complexity of the asynchronous HTTP request for this specialized case. For example, take the code that handles selection of user roles from the Hydro4GE database:
  public class SelectRoleHandler implements DatabaseRequest.Handler {
    public void handle(DatabaseRequest.Result result) {
      for (int row=0; row < result.getRowCount(); row++) {
        JSONObject data_row = result.getRowValues(row);
        Role r = new Role(data_row);
        // process role...
Compare this to the code that you would typically write for an HTTP request callback:
  public class SelectRoleCallback implements RequestCallback {
    public void onError(Request request, Throwable exception) {
      Window.alert("Couldn't retrieve JSON");

    public void onResponseReceived(Request request, Response response) {
      if (200 == response.getStatusCode()) {
        JSONArray data_set =
        if (data_set != null) {
          for (int row=0; row < data_set.size(); row++) {
            JSONObject data_row = data_set.get(row).isObject();
            Role r = new Role(data_row);
            // process role...
      } else {
        Window.alert("Couldn't retrieve JSON ("
            + response.getStatusText() + ")");
Besides being easier to understand (and half as many lines!), the Handler code has the advantage over the Callback in that multiple independent handlers can be attached to a single request in order to achieve separation of responsibility in handling each response. In addition, each handler is isolated from the results of other commands in the same request, so that there is no confusion over which results you are handling. This example does not even introduce the complexity of handling multiple command responses in the typical RequestCallback code, but the Handler code supports it implicitly by its nature.
These concepts can and should be applied to GWT-RPC or any other communications encoding. The implementation details are different, but the spirit is the same: make every HTTP request really count.


The techniques I have demonstrated here can be used equally effectively in both new and existing projects. Whether you are trying to build a slick UI, wrap an external library, or talk to a server, I have only scratched the surface of what is possible with GWT. I am especially looking forward to GWT 2.0 for continued improvements on some of the topics covered here, made possible by some exciting upcoming features such as UiBinder and CssResource.
In short, I am pretty excited about GWT and Hydro4GE, and I hope you are too. Be sure to check out the sneak peek of Hydro4GE to see a demo of our GWT UI in action!
Geoffrey C. Speicher, MS is a Software Engineer at Software Engineering Associates and the Chief System Architect of Hydro4GE.

1 comment:

CHEM_Eugene said...

How I can repaint MyDrawing if I add new shapes?