A Solution to perform GWT RPC calls from within a Wave Gadget

June 25th, 2010

The Problem

When you’re building a Google Wave Gadgets with GWT you might want to communicate with the server via RPC, because that’s any easy way to communicate. Until now it was not really possible to do. The reason, the standard RPC implementation works only when the client application is loaded from the same server to which the RPC calls are made. This is due to the cross-site restriction browsers enforce to avoid harmfull actions performed by malicious sites. The problem is that Wave caches the gadget and runs it from it’s own server, instead of the originating server, and thus when the Gadget is loaded and runs, the original server is now on another domain, and therefor it’s not possible to perform the standard RPC calls.

The Solution

The solution lies in the iGoogle Gadget api. Wave Gadgets are build upon the iGoogle Gadget api and the Gadget api contains a proxy method to perform RPC calls to another server. Calls are routed through the iGoogle Gadget proxy server and for the client, the gadget code, it seems as if it performs a direct call to the external server. This is nothing new. However, there was not yet a GWT wrapper for access to these Google Gadgets api calls, and thus you would have to write that yourself.

But that’s about to change. When I was informed by the GWT team they where working on a new release of the GWT Gadget api I noticed the wrapper for the iGoogle proxy methods were added and wrote additional code to make it easy to do actual RPC calls from Wave. Now this code has been added to get GWT Gadget api library and will be present in the comming release. The trunk already contains these method, so if you want to start today, build your own version of the GWT Gadget api from trunk.

How To

Making RPC work within a Wave GWT Gadget is now easy. With these 2 steps any GWT Gadget can be made to work to use RPC.

1) For each service you want to use you need to redirect it to the Gadget api proxy to perform RPC call. This is done with the static method redirectThroughProxy. As shown in the following example:

  YourServiceAsync yourService = GWT.create(YourService.class);
  GadgetsGwtRpc.redirectThroughProxy((ServiceDefTarget) yourService);

2) On the server side you need to override the method readContent in your servlet implementing the service, the one extending RemoteServiceServlet:

  @Override
  protected String readContent(HttpServletRequest request)
      throws ServletException, IOException {
    return RPCServletUtils.readContentAsUtf8(request, false);
  }

This is needed because the current implementation of the iGoogle Gadget and thus Wave proxy rewrites the content type header and the GWT RPC implementation checks for this type to be text/x-gwt-rpc.

One Final Remark

Wave Gadgets can store state in the Wave itself. When storing state it’s also available in the Wave’s history. When you decide to store state on your own server, via RPC, you need to take care of showing historic versions yourself. This means depending on the case it’s better to store state in the Wave instead of obtaining the data from your own server.

Thanks to the GWT team for adding the code and make it easy to perform RPC calls from within Wave Gadgets.

To easily write Wave Gadgets with GWT use the cobogwave library that wraps all Wave specific methods.

Update June, 28: The new iGoogle GWT Gadget api is available for download. Version 1.2: http://code.google.com/p/gwt-google-apis/downloads/detail?name=gwt-gadgets-1.2.0.zip

Update for cobogwave, the GWT wrapper for the Wave Gadget api: support for Private State and new Wave styled UI widgets

May 17th, 2010

Just in time for GoogleIO 2010. Here is the updated version of the cobogwave library, the GWT wrapper for the Wave Gadget api. Recently, the Wave gadget api got some new features, and now the GWT wrapper library supports this new functionality.

Private State

State values stored in a gadget are global for every viewer of the wave containing the widget. Changes made by one of the viewer are seen by all other viewers. With the new api changes, it’s now possible to store private state. This means those state values are only accessible by the viewer who made the changes. Private state can be used to store data for a viewer, that should not be accessible or seen by other viewers.

Wave styled widgets

In the wave gadget api there are 3 methods added to create ui widgets with a Wave style. While it doesn’t seem to be supported officially, the cobogwave GWT wrapper now provides access to those methods such that they can be used as standard GWT widgets. The 3 widgets made accessible are: Button, DialogBox and DecoratedSimplePanel.

Button An anchor styled as button.

Wave button

DialogBox A DialogBox styled as a Wave dialog box.

Wave DialogBox

DecoratedSimplePanel A GWT SimplePanel with Wave style.

Wave DecoratedSimplePanel

Download the cobogwave library at http://code.google.com/p/cobogwave/.

“Recreating the button” in GWT

March 8th, 2009

On 3 Februari 2009 Google launched their new “custom buttons” in Gmail. The idea and creation process behind these buttons were described in the blog post Recreating the button at stopdesign.com, who were part of the process to develop these buttons. The buttons were designed for the following reason:

The buttons are designed to look very similar to basic HTML input buttons. But they can handle multiple interactions with one basic design. The buttons we’re using are imageless, and they’re created entirely using HTML and CSS, plus some JavaScript to manage the behavior. They’re also easily skinnable with a few lines of CSS, which was a key factor now that Gmail has themes.

Unfortunately, as with many UI widgets created by Google, these are not made publicly available via their GWT framework. Therefor I decided to recreate the button in GWT. I’ll describe some of the JavaScript and CSS issue I faced and how these were solved. If you want to go straight to the button and demo here are the relevant links: download, demo. Javadoc: Button and ButtonBar

Example of using the button in GWT

Example of using the button in GWT

Design

The Button widget has been designed to look as close as possible to the look and feel of the Google button (read: pixel perfect). To make the usage of button easy it has same class interface as the PushButton widget from the GWT library, this makes it easy to replace existing buttons with the new Button widget. Additional there are several methods to easily change the color, size or text/button ratio. For the color I added a method that based on a hue and saturation value calculates all colors needed. This makes it easy to change the color of the button.

The button is constructed with nested <div> element’s. You can easily see this when you view the button with your favorite browser code inspector tool. Eventually I ended up with one <div> element less than in the Google button, which didn’t effect the layout as far as I my tests concluded.

JavaScript and CSS issues and fixes

After the basic reverse engineering I fixed the specific browser support issues, mainly related to the inline-block support. In the process the free browser testing service browsershots.org was of great help. But service only helps you with layout issues, not if the effects and actions work correctly. The Internet Explorer Application Compatibility VPC Image make it possible to test different versions of Internet Explorer. In the end I only didn’t fix IE 6 issues yet. Here are some details regarding the major issues:

DOCTYPE

It turned out that to display the button correctly in Internet Explorer 7 you need to set a DOCTYPE. It doesn’t matter which one, you just need one. So don’t forget to set one!

display:inline-block

What is interesting about the google button, is the use of the display property value inline-block. This property can be used to position block elements horizontally without having to float them. Because browser support has been very poor and using it is was not recommended. But newer browsers do support it and it won’t be long before you can safely use this property value.

Of the major browsers, support in Internet Explorer 7 can be achieved via the hasLayout trick, used in the button widget by setting display:inline and zoom:1 instead of display:inline-block. In the cobogw library there is a method CSS#setInlineBlock that will take care of different browser implementations.

Unselectable button text

If you check the Google button you will see that’s it’s not possible to select the text. Making text unselectable is normally not considered good practice, but in this case a normal button is also not selectable. But making something unselectable differs almost is all browsers. In the cobogw library there is a method CSS#setSelectable to take care of different browsers.

A small related issue is with Opera. In Opera when a user selects an element with a tab index it gets a different background color. For Opera 9.5 and later this can be removed via the CSS3 pseudo element ::selection. However, I didn’t find any way to set this via JavaScript, which means you need to set this in your own CSS file. This is documented in the Button JavaDoc.

Fire click event

A <button> element triggers a click event in case the user hits the space bar or the return key. However, a <div> element doesn’t have this behavior so programmatically a click event must triggered when the user hits one of those keys. It turns out this is also browser specific. IE does support the JavaScript method click() on the <div>. In the other browsers you need to do somewhat more. In short, you need to create a MouseEvents and call the dispatchEvent method on the <div> element with the a click event object.

For most other use cases it should not be needed to fire events that are normally only triggered by user interaction. If you find yourself doing such and are not creating ‘low’ level widgets like buttons you probably should reconsider your code. A method fireClickEvent that takes care of different browser implementations is available in the cobowg library to fire a mouse click event.

New name: cobogw.org, new widgets and GWT 1.5 support

August 13th, 2008

Today I moved the gwt.bouwkamp.com project to a new name: cobogw.org. I guess, it’s completely unpronounceable ;-), but I like abbreviations, the domain was free and the name isn’t used. That can be an issue nowadays. The new name is to better reflect the open source nature of the project (moving from a .com extension to a .org). The new project is hosted on google code, just as the old project was, http://code.google.com/p/cobogw/ (Or you can reach the project site via www.cobogw.org).

New release, GWT 1.5 support

I’ve released a packaged version of the cobogw project, which contains an easy to use jar file containing all widgets, source code and javadoc. With this release some new widgets are added and the jar file is also available as as GWT 1.5 compatible only version. You can find the zipped files at the download site. The new widgets/classes are:

  • Rating - A widget that allows users to set ratings (demo).
  • Span/TextNode - Widgets to add span an textnode tags to other widgets without overhead of additional div tags (demo).
  • CSS - A helper class to help with CSS properties.

On the project site you can also find examples and javadoc documentation for existing and new widgets.

Let me know what you think of the new name and new widgets.

Fixing java.sql.Date/Time/Timestamp support for GWT

December 12th, 2007

Probably anyone who uses the sql Date/Time or Timestamp classes and wants to use these in GWT needs wrap a custom implementation around these classes on the server side, because the java.sql classes are not supported by the current version of GWT (1.4.61). This is because for existing classes, like java.lang.String, GWT provides an emulated version. These are implemented for a large number of the java.lang objects among others, but not for these java.sql classes.

I had the same problem. I use Spring/Ibatis and maintained 2 data objects one on the server side used by Spring/Ibatis and on the client side which instead of the java.sql.Date used java.util.Date. The latter was used to communicate the data between the client and server.

When looking for a solution I found the problem was reported some time ago under issue 87 in the GWT issue tracker. But it’s marked with Priority-low. Furthermore, hibernate4gwt offers a solution, but I looked at the implementation of the emulated classes and missed some functionality. Therefore I wrote my own implementation to support java.sql.Date, java.sql.Time and java.sql.Timestamp to be fully compliant with the JRE classes (as far as is possible).

I prefer simplicity and packed the classes in a jar file, which you can simply place in your classpath to add support for the java.sql.Date, java.sql.Time and java.sql.Timestamp classes (presumingly you have already added User.gwt.xml to you module).

Download of the jar file, packed in a zip: cobogw.java.sql-1.0.zip

Because quality is important I created JUnit test cases to check the implementation. You can find the reports and test classes in my cobogw project repository.

Lessons learned

October 7th, 2007

I’ve been working with GWT for more than a year and still think it changed the playing field. Joel Spolsky wrote an article about how GMail can be compared to what happened to Lotus 1-2-3 and that Google should watch out for some SDK that will change the landscape. I think that SDK can be GWT. Here are some lessons I’ve learned:

  • The GWT library takes away a lot of the burden of browser incompatibility related to JavaScript and therefor I don’t have to worry about browser JavaScript incompatibility. For new applications there are very few reasons to write your own JavaScript, unless you want to use a specific JavaScript or DOM element not accessible via GWT or want to integrate a some existing JavaScript code. Although when rewritten in GWT (i.e. Java) you can better debug the code.
  • What GWT does for JavaScript it doesn’t do for CSS or HTML. Which means that you still have to work around any CSS or HTML specific browser incompatibilities. CSS and HTML knowledge is very much required. I wrote a CSS helper class that contains all possible items and works around the ‘float’ issue. I’ve not released it officially but you can find it here (make sure you have all files and inherit the CSS.gwt.xml (or Users.gwt.xml)).
  • Programming GWT applications can be compared to writing classical GUI applications, like Java SWING applications.
  • Websites are created by web designers, who understand HTML and CSS, but probably are less familiar with programming. In GWT the whole design must be rewritten in GWT widgets, and none of the HTML created in the design can be reused. This makes the design/develop process more complicated.
  • In GWT there are two ways to set the style on HTML tags: programmatically and via CSS. The advantage of putting something in CSS is that it is easy to test your layout. I use the web developer extension in Firefox to dynamically alter the CSS style of an HTML page. When I’m satisfied with the style I hard code those properties that should not be changed, because when set differently they would break the layout. This makes reuse of the code more easy.
  • GWT does add a different dimension to HTML design. Because you develop in widgets and less in terms of HTML tags the notion of what is considered bad and good use of HTML blurs. For example, tables are considered bad it is better to use divs, the same for innerHTML. But all is hidden behind widgets. It becomes something you don’t care about. Although you have to because of the style differences between browsers on divs and tables. Some widgets are based on tables and could be rewritten in divs, but I found this very hard. I did a rewrite of the TabPanel widget with only divs, but to the implementations only worked if I didn’t use ‘quicks mode’.
  • With GWT you write in Java and debug your application in Java which makes it very easy to debug your code. Debugging is at Java language level, you are not debugging JavaScript. If you have custom JavaScript and you need to debug the JavaScript, you need to debug it using an external JavaScript debugger, which means you need to debug the generated code. I have not needed this, since I didn’t need any custom JavaScript, except for a few lines to set a very specific attribute not accessible via GWT.
  • GWT does lock you in. This means once you’ve writing your application in GWT ‘Java’ you can’t easily move it to some other library. The lock in is comparable with when you write your application in a specific programming language. For example if you would write you application in C# it’s not easy to move to some other language or library. The lock in is not necessary a bad thing because GWT is based on open source software and is open source itself, which is a good thing.
  • What is important to remember is that although you code Java for the client side it isn’t Java you’re writing. You are writing an application using Java syntax which is compiled to JavaScript. This is important to understand because it basically means you are writing in an unspecified language. This is partly true because in hosted mode your application runs as a Java program which means it really is Java. But eventually when you deploy your code it will be compiled to JavaScript. It also means that you can only use a very small set of the standard Java library, which is supplied with the GWT library.
  • The GWT compiler is currently limited to Java 1.4 syntax (Java 1.5 syntax is planned for GWT version 1.5). However, this doesn’t limit you to use JAVA 1.5 or 6, you simply can’t use specific Java 1.5 syntax in the client code. For the server side you can use whatever Java (syntax/library) you want.

Updated RoundedPanel

April 30th, 2007

Last year I created a small widget to create rounded corners similar to those in Google mail and calendar. While working with the widget I updated the RoundedPanel Widget with several improvements and changes:

  1. The height of the corners can be set. In the previous version this was set to 2. In the new version you can set an index between 1 and 9. I call this an index, not the height, because the real height is somewhat out of sync simply to get better looking rounded corners. For example using 9 will get an real height of 12px.
  2. The color of the corner can be set via a method, setCornerColor. This method sets the background of the corner div’s. This method is helpful to programmatically change the colors.

I created a project on the Google code site where the the latest sources will be maintained as well as issues found and where I will release new widgets, like the VerticalTabPanel: http://code.google.com/p/com-bouwkamp-gwt/

Vertical TabPanel

April 12th, 2007

The default TabPanel in GWT supports only a Horizontal TabBar. If you want to create a TabPanel which has a Vertical TabBar on the left side of the TabPanel you need to create a complete new implementation, because it is not possible to subclass the TabPanel class and modify the layout. Take the KitchenSink example. This is a Vertical TabPanel, but not implemented as one. With a VerticalTabPanel you can get the same layout.
The following 2 classes are modified versions of the TabPanel and the TabBar to display as a VerticalTabPanel:

VerticalTabPanel.java

VerticalTabBar.java

Notes:

The TabPanel and TabBar are based on the not yet released GWT 1.4 TabBar, which include the feature to add widgets to the tabBar.

Furthermore, I added the method getSelectedTabWidget which returns, just as it implies, the widget of the selected tab. This can be useful if you want to dynamically change the style on a selected tab, for example set a different background color.

The basic infrastructure

March 5th, 2007

Before I know it I’m almost 3 months further and no posts yet…. When I started developing an application with GWT I soon found out I needed a basic infrastructure to speed up the development.

Part of the infrastructure is the Java servlet engine and how it works. A good start is the Java servlet specification: servlet-2_4-fr-spec.pdf, which you can download here from the sun site. This describes all standard functionality, which you get from a servlet engine, like Tomcat.

I started with a basic look and feel similar to Google Mail and Google Calendar or also available in the GWT Kitchen Sink example. The features I want are the list on the left side, the main panels, a settings panel and a feedback panel at the top which is shown when errors occur or after some user action. To be able to develop my own application faster I first decided to build a basic framework that handles all these panels and to build my application up on this framework. That way I don’t have to worry about basic features and can focus on the features I want in my application. I plan to release the framework when its finished. I have no planning but I don’t hope it will take another 3 months…

First post!

December 17th, 2006

The purpose of this blog originates from my interest in building web based applications (also referred to as AJAX or Web 2.0). Ever since Google released their Google Web Toolkit I have been interested in the possibilities of this new way of developing web based applications.

Initially I developed a small widget to get rounded corners (see: gwt.bouwkamp.com). But I started to think about developing a real life application based on this toolkit and see if this technology is up to that task. Because my interest in personal finance applications and the lack of good applications I decided that a web based personal finance application is a perfect case.
On this blog I hope to write about the progress, development (struggles;-), post idea’s and code.