TurboManage

David Chandler's Journal of Java Web and Mobile Development

  • David M. Chandler


    Web app developer since 1994 and former Developer Advocate with Google now residing in Peru. I am currently offering public and private developer training courses in the US and Latin America as well as working on Android, GWT, and App Engine projects.

  • Subscribe

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 220 other followers

  • Sleepless Nights…

    July 2014
    S M T W T F S
    « Jun    
     12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
  • Blog Stats

    • 641,488 hits

Archive for the ‘Google Web Toolkit’ Category

Painless REST+JSON API with Jersey and RestyGWT

Posted by David Chandler on July 23, 2014

It’s been a while since I’ve been active in GWT programming, but I recently picked up an old GWT + App Engine project and dusted it off. This time around, I need a service layer that will work with native mobile apps as well as the GWT desktop app: in other words, a REST+JSON API.

The server side

I decided to use Jersey on the server, which makes it incredibly easy to create REST services, especially in combination with the fabulous objectify-appengine. Here’s one of my services:

@Path("api/user")
@Produces(MediaType.APPLICATION_JSON)
public class UserDao extends ObjectifyDao<User>
{
    @GET
    @Path("me")
    public User getMe() {
        return AuthFilter.getUser(); // long live ThreadLocal!
    }
}

All the other standard CRUD methods (list, get, delete, etc.) are inherited from a generic DAO. A servlet filter verifies user authentication, XSRF tokens, etc. At only one class per entity, I find this much more agreeable than the four classes per entity I used to write with gwt-dispatch (Action, Result, Handler, DAO).

The GWT REST+JSON client

On the client side, GWT developers have long needed something which combines:

  1. The convenience of GWT-RPC (automatic serialization of pretty much everything)
  2. JSON data format
  3. Simple verb-based service APIs
  4. Benefits of the command pattern such as request caching and batching
  5. Minimal boilerplate

RestyGWT delivers on all counts.

The interface is actually simpler than GWT-RPC because you don’t have to define a synchronous and asynchronous method, only async (although you can reuse the server interface and call it using DirectRestService if it helps you sleep better). Here’s a sample interface using RestyGWT. This is a generic CRUD API which I simply extend for each entity class.

public interface RestApi<T> extends RestService {

    @GET
    @Path("own")
    public void getForOwner(MethodCallback<T> callback);

    @GET
    @Path("get")
    public void get(@QueryParam("id")Long id, MethodCallback<T> callback);

    @GET
    @Path("all")
    public void listAll(MethodCallback<ListResponse<T>> callback);

    @POST
    @Path("save")
    public void save(T obj, MethodCallback<T> callback);

    ...
}

Here’s a sample service API and the GWT code that calls it:

public class UserPrefsService
{
    private static final UserPrefsRestService service = GWT.create(UserPrefsRestService.class);

    @Path("/api/userPrefs")
    public interface UserPrefsRestService extends RestApi<UserPrefs> {
        // just in case you missed it, all the CRUD methods are inherited
    }

    private UserPrefs prefs;

    public void loadUserPrefs()
    {
        service.getForOwner(new AppCallback<UserPrefs>() {
            @Override
            public void handleSuccess(UserPrefs result) {
                prefs = result;
                App.getEventBus().fireEvent(new UserPrefsLoadedEvent(prefs));
            }
        });
    }
}

I really like the benefits of the Command pattern from the old gwt-dispatch framework such as the ability to do caching and queuing centrally. The downside of the Command pattern is the proliferation of classes associated with turning every API method into two or more classes (in the case of gwt-dispatch, an Action and Result class for every service method). GWT’s RequestFactory (the GWT team’s “final answer” to RPC after GWT-RPC and deRPC) used generators to remove some of the boilerplate, but I wasn’t in love with having to call someSingleton.getRequestFactory().someRequest().create(BeanProxy.class) each and every time I wanted a new Bean. Also it’s been deprecated. And it uses a proprietary data format, not REST+JSON.

This is where RestyGWT really shines. It lets you define simple API interfaces using methods, but uses a Command pattern dispatcher under the covers with an ingenious filter mechanism for adding capabilities like XSRF protection, caching, and retries. The magic is possible thanks to RestyGWT’s generator classes which transform your annotated service methods into MethodRequest classes that get sent by a dispatcher. To add caching capability to all your APIs, for example, just put this in your GWT onModuleLoad():

DispatcherFactory factory = new DispatcherFactory();
org.fusesource.restygwt.client.Defaults.setDispatcher(factory.cachingDispatcher());

For a look at some of the other dispatcher options, have a look at the RestyGWT User Guide and the example DispatchFactory class.

Tips for success with Jersey + RestyGWT

Just a couple final notes to ease your migration to Jersey + RestyGWT.

If you’re using RestyGWT with Jersey + Jackson on the server, you’ll want to set the default date format to avoid Date serialization errors. Put this in your GWT’s onModuleLoad():

Defaults.setDateFormat(null);

Similarly, recent versions of Jersey complain about “self-referencing cycles” or some such with Objectify’s Ref properties, so you’ll probably want to annotate those in your server-side entities with @JsonIgnore. If you need the id of a related object, use a differently named getter instead. Jersey will create a corresponding JSON property. Example of an Objectified entity on the server:

package com.my.server.domain;

@Entity
public class UserPrefs {
    @Id
    private long id;
    @JsonIgnore
    private Ref<User> ownerKey;
    ...
    public long getOwnerId() {
        return ownerKey.get().getId();
    }
}

Then on the client you can reference the ownerId property:

package com.my.client.domain;

public class UserPrefs
{
    public Long id;
    public long ownerId;
    ...
}

I would prefer to use the same object representation on client and server, but RestyGWT makes using DTOs about as painless as possible. The client-side object is a class not an interface, so you can create a new instance anywhere you need it vs. having to GWT.create(BeanProxy.class). I could probably hack Jersey and maybe objectify-appengine to automatically replace all Refs with a long id, but honestly, it’s easy enough just to copy the server entities and replace Refs with long ids on the client.

Also, here’s a pair of classes you may find useful for sending any type of list from server to client. For security purposes, a JSON response should always return a root object, not an array directly. The ListWrapper (server) and ListResponse (client) serve as this root object, having a single field containing the list.

package com.my.server.domain;

/**
 * Wraps a List<T> in a JSON root object.
 */
public class ListWrapper<T> {
    private List<T> list;

    public ListWrapper(List<T> list) {
        this.list = list;
    }
    public List<T> getList() {
        return list;
    }
}

Use it like this in one of your Jersey-annotated methods:

    @Path("all")
    @GET
    public ListWrapper<Subscription> findAll() {
        User user = AuthFilter.getUser();
        List<Subscription> userAll = this.listByOwner(user);
        return new ListWrapper<Subscription>(userAll);
    }

Using ListWrapper this way has the additional advantage of causing Objectify to fetch any lazily loaded properties such as Refs used in the getOwnerId() method above while producing the JSON. If you were to return the List directly, this would not occur!

Here’s the corresponding representation on the client:

package com.my.client.domain;

public class ListResponse<T> {

    public List<T> list;

}

See the RestApi example earlier for how it’s used.

Summary

Jersey and RestyGWT in combination make a powerful and easy way to create a REST API for your GWT client and mobile apps, combining all the benefits of a request dispatcher with straightforward service interfaces and minimal boilerplate.

Happy coding!

Posted in AppEngine, Google Web Toolkit | Leave a Comment »

GWT, App Engine, maven, and… IntelliJ!

Posted by David Chandler on June 5, 2014

I’ve been putting off migrating to Android Studio for a while now because I’m frankly loathe to learn a new IDE. I’ve used Eclipse for a decade and grew to become very productive in it. But a completely different team at Google may have just well forced me into it.

When I joined the GWT Developer Relations team in 2010, I worked closely with the Google Plugin for Eclipse team to get maven support into GPE. With their excellent work, we eventually achieved the holy grail: you could import a POM containing maven-gae-plugin and gwt-maven-plugin into Eclipse and all the GWT + GAE stuff from GPE like launching dev mode would just work (well, if you had the right supporting plugins like m2e-wtp). So the other day, I picked up a POM that worked in those days and tried it out on Kepler + GPE + m2e-wtp. Amazingly enough, the GWT stuff still works. Google now supports its own appengine-maven-plugin, so I swapped out the old GAE plugin for the new. It’s supposed to work with GPE and WTP, but so far no dice. It will be great when they get the kinks worked out. Funny thing is, I remember seeing exactly the same problem with GAE-maven integration way back in my GWT days. Only then, I could just walk over to Rajeev’s desk and he would fix it :-)

In the mean time, imagine my surprise to discover that I could just import the POM into IntelliJ (full edition) and everything works. The maven project imported, I can launch GWT dev mode, set breakpoints and debug, etc. It’s funny to me that JetBrains can keep up to date with Google App Engine better than the GPE team, but that’s how big companies move sometimes….

So I’m off to learning new keyboard shortcuts (I could use the Eclipse keymap, but I had customized Eclipse, too. It’s easier than I thought to learn new tricks). And I have to say, the performance of IntelliJ is impressive. A couple of my teammates way back at Intuit will no doubt be glad to hear that I finally came around to maven + IntelliJ, not to mention some of my Android DevRel mates. We’ll see how this goes, but so far, I’m impressed.

 

Posted in AppEngine, Eclipse, Google Web Toolkit | 1 Comment »

The History and Future of Google Web Toolkit

Posted by David Chandler on July 11, 2012

I’ve eagerly anticipated this blog post. There is a lot I have wanted to say about GWT in the past year, and Ray Cromwell says it all in this candid and optimistic Google I/O session.

Highlights

  • There are over 100k active GWT developers world-wide
  • GWT 2.5 RC1 is now available with many code size improvements and some long-awaited new features (SourceMaps, SuperDevMode, and Elemental)
  • Google is moving from gatekeeper to peer among equals on the newly formed GWT steering committee
  • GWT trunk is now open for commits by external parties (no Googler intervention required)
  • Sencha has released GXT 3, a major refactoring built on true GWT
  • Vaadin will be offering commercial support for GWT
  • Mgwt is awesome (Mobile GWT, works with Phonegap)

Markers

  • 12:05 Introducing SourceMaps and SuperDevMode
  • 25:40 Future of GWT
  • 29:45 Michael Mullany, Sencha
  • 39:58 Joonas Lehtinen, Vaadin
  • 49:30 Q&A

Summary

I think it’s obvious to everyone that the GWT team at Google has shrunk significantly over the last year; nevertheless, GWT 2.5 demonstrates that GWT is still moving forward at Google as well as in the open source community. I think enterprises will be especially interested in Vaadin’s first-ever commercial support for GWT, and Sencha GXT customers will likewise be glad to see Sencha on the GWT steering committee. As a mature framework, GWT may not attract the attention and resources associated with the Next Big Thing, but at the same time, GWT 2.5 is better than ever for building large-scale rich Web apps and cross-platform mobile apps in the enterprise.

Posted in Google Web Toolkit | 1 Comment »

Troubleshooting App Engine-connected Android projects with c2dm

Posted by David Chandler on May 18, 2012

Google Plugin for Eclipse has a wizard to create an Android project with App Engine back end including client push (c2dm). The official tutorial is quite good, but after spending the better part of a day trying to get the Cloud Tasks sample up and running again, I thought it might be useful to post a few tips.

General Tips

  • Sign up for c2dm first. Remember the package name and use it when running the Eclipse wizard! The package name is required, and once you choose the package name on c2dm sign-up, it is nowhere visible later. Be patient–it may take an hour or even a day to activate your account.
  • Sign in to Eclipse with the c2dm account name you’ll use (see lower left corner–if not visible, you need Google Plugin for Eclipse). It’s easy to forget this, but Debug As | Local App Engine Connected Project requires you to be signed in.

Run on a Phone With the GAE Dev Server

In this scenario, the phone and dev server must be on the same network! Easiest way is to connect to the same wi-fi router. USB cable does nothing. Be aware that most public wi-fi routers don’t allow devices to contact each other, so it will probably work best at home or on your company’s guest wi-fi network.

  • Ensure that phone and dev server are on the same wi-fi network. Disconnect both from any VPNs.
  • Add -bindAddress 0.0.0.0 to your Web project’s Run Configuration | Program Arguments. This will start the server listening on all addresses, not just the default localhost (which the phone can’t see).
  • When you choose Debug As | Local App Engine Connected Android Application, GPE hardcodes your machine’s IP address in assets/debugging_prefs.properties. This is where the Android app looks up the address of the server.
  • You can launch/debug the Android app and the Web app independently; however, if your server IP address changes, you must again Debug As | Local App Engine Connected Android Application in order to update the IP address in assets/debugging_prefs.properties.
  • In case you wondered, the Android and Web projects are associated in a file in the Android project. You can find it in .settings/com.google.gdt.eclipse.mobile.android.prefs. To associate a different App Engine project with an Android project, simply edit this file and refresh the project.
  • If you’re using the GWT dev mode browser plugin, you can still connect to 127.0.0.1. If you connect to the address shown in Development Mode tab (your machine’s network IP address), you may need to allow the address in the dev mode browser plugin. Click the GWT icon in the address bar to do this.
  • Make sure you log in to the Web app as the c2dm user, not the default test@example.com.

Run on a Phone Against the Production App

In the production scenario, you’re using real c2dm so the phone doesn’t have to be on wi-fi at all.

  • Edit Setup.java and change APP_NAME and SENDER_ID to match your GAE app id and c2dm account.
  • Change app id in appengine-web.xml to match your GAE app.
  • Deploy to App Engine with your c2dm account.
  • Force sign in to GAE app by going to [prod_url]/tasks/. This triggers the security constraint in web.xml to get logged in to GAE. After logging in, you’ll get an error page, but that’s OK. Then go to [prod_url]/ and Say Hello to App Engine. If logged in, you should see a success message.
  • If you’ve previously connected an account on a phone to this production app, go to GAE datastore viewer and delete all records.
  • In Eclipse, Debug as | Remote App Engine Connected Android project
  • On the phone, you’ll be prompted to connect an account. Use your c2dm account. If you have previously connected a different account, go to Menu | Accounts | Disconnect in the app and reconnect.

The CloudTasks project still has a few issues. Feel free to log them in the tracker.

Posted in Android, AppEngine, Google Web Toolkit | 7 Comments »

Is the mobile Web ready for business app developers?

Posted by David Chandler on March 15, 2012

Disclaimer: these thoughts are my own, not necessarily those of my employer.

I recently attended A Night with Sencha and Ted Patrick, and it got me thinking more about the mobile web. Mobile developers are clearly hungry for cross-platform solutions like Sencha and Titanium, and HTML5 promises significant cross-platform compatibility. (Action game developers, you can stop reading now because you already know that the high-performance mobile Web is not there yet. In fact, many folks I talked to last week at GDC are not even using the Android SDK, but rather the Android Native Development Kit to port games from iOS in C.)

Having said that, the mobile web for business app developers is arguably the easiest way to develop mobile apps, period, even without the side benefit of cross-platform compatibility. Why?

  • Web development frameworks is a rich and mature space. There are dozens of well-established popular frameworks on both client and server for MVC, CSS, JSON, etc. We’ve been doing Web development for almost 20 years now.
  • Web design tools abound. Although IDEs for native apps offer design & layout functionality, more designers are familiar with tools like Dreamweaver for HMTL+CSS. Firebug and Chrome DevTools are the ultimate WYSIWYG editors. Who wants to learn another style language when you’ve finally conquered CSS (kicking and screaming)?
  • Mobile browsers, like their desktop cousins, offer great tools for design and debugging (such as Safari Web Inspector and remote debugging with Chrome Beta for Android). Tools like the Window Resizer Chrome extension let you quickly test your app in a variety of different resolutions.
  • Frameworks like Sencha do a lot of the heavy lifting around RPC, local storage, dynamic UI creation & data binding. These things take a lot of work to do correctly in a native app.
  • You don’t have to worry as much about device compatibility. Mobile browsers aren’t perfect and there are still compatibility gaps (see mobilehtml5.org), but most players in the ecosystem are motivated to ensure that the browser runs well on all devices. The ecosystem is probably less concerned with your apartment finder app. Provided you’re using standard browser features, the browser vendor bears much of the testing burden.

So why does anyone write native apps?

  • Monetization, of course. But you can wrap your app in a WebView. As far as I know, WebViews aren’t an issue in any of the app markets with the possible exception of Apple, and according to Ted Patrick, Apple has been good about letting WebView apps in “once they get to know you and find that your app is reliable.” YMMV.
  • Native look and feel. Sencha / jqTouch does a convincing job with this on iOS. I haven’t seen it on Android.
  • Performance. I already mentioned this with respect to fast-moving games, but most business apps don’t use Canvas or a lot of CSS transitions. And with care, even large apps that manage a lot of data (like mobile GMail for the Web) can be snappy.
  • Hardware access. With HTML5, you can get the user’s location and even the accelerometer, but not the camera. At least not yet. But for most business apps, location is all you need.
  • Integration with the OS. If your app needs a ContentProvider or background Service or handles Intents, then you do indeed need a native app. Several well-known apps are succeeding with a hybrid approach, however, by using WebViews for rendering and native Services for data access. This simplifies the UI design as noted earlier while retaining other advantages of the platform.
  • Finally, native apps let you write code in something other than Javascript. Of course, you could try GWT or Dart and compile to JS, too. Ironically, many of the native cross-platform solutions also require you to write your app in Javascript.

Over the next few weeks, I’ll be porting my listwidget app to native Android and mobile Web using a variety of technologies. I’ll keep you posted.

Posted in Android, Dart, Google Web Toolkit | Tagged: , | 1 Comment »

HTML5 and GWT @ Rich Web Experience

Posted by David Chandler on November 30, 2011

Here are the slides from my HTML5+GWT talk at Rich Web Experience:

Building Mobile and Enterprise Apps with HTML5 and GWT

The talk is very similar to the combined GWT and Dart talk I gave at SenchaCon last month, which you can find at www.dartlang.org/slides/.

Posted in Google Web Toolkit | 8 Comments »

Google Plugin for Eclipse now open source

Posted by David Chandler on November 16, 2011

This is pretty big news for the GWT community and should make it easier for GWT frameworks to build tooling for Eclipse. Witness JBoss, who was working on GWT integration even before the announcement. Congrats to the GPE team!

Posted in Eclipse, Google Web Toolkit | Leave a Comment »

DART slides from SenchaCon

Posted by David Chandler on October 28, 2011

I thoroughly enjoyed SenchaCon this week in Austin, TX, where I presented Building Modern Web Apps with HTML5 and DART. Overall, I was very impressed with the quality of the developers at SenchaCon. It was a special treat to meet Darrell Meyer and Sven Brunken, lead developers for Ext GWT. In the last year, Ext GWT has undergone a huge refactoring to do things more consistently with vanilla GWT (including Cell widgets and the Appearance pattern), and now makes advanced use of these as well as the new AutoBeans framework. I regret not meeting Darrell, Sven, Colin, and team sooner, as they are clearly sophisticated GWT developers who understand the innards of GWT quite well and have taken pains in the last year to make Ext GWT more interoperable with mainline GWT, including throwing away some of their previous work when GWT rolled out with the same functionality unanticipated. I frequently get asked about GWT consulting and am delighted to learn that Sencha has a growing professional services team knowledgeable about GWT as well as all things browser. This is not an official endorsement, but Sencha certainly appears to be one of the few companies capable of handling large GWT projects.

I had lots of fun watching developers interact with the Chromebooks on display in the Chrome booth. Many folks mentioned getting one for their kids or grandmas this Christmas (“and give yourself the gift of no tech support”). I am personally more attracted to the Chromebook than tablets, but that’s mostly because I’m so keyboard-focused (the trackpad on the Samsung Chrombook, by the way, is one of the better I’ve used apart from a Mac–I haven’t tried the Acer Chromebook yet). One place where a tablet would excel is crammed in the back of an airplane, where there’s not really enough room to open my 15″ MacBook Pro. Speaking of which, flights are much more bearable with a laptop and wi-fi. I think I’m addicted to work.

Back to Dart. I regrettably did not leave any time for questions, but was pleasantly surprised at feedback from JS developers after my talk who expressed frustration with Javascript’s lack of typing and scoping and were cautiously optimistic about Dart as a better way to build large-scale apps in the browser. I also met folks who are currently building large apps in JS by compiling from ActionScript. The fact that people are doing this (along with compiling from Java using GWT) definitely points to the need for better languages in the browser.

 

Posted in Dart, Google Web Toolkit | 4 Comments »

First thoughts on Dart from a GWT developer

Posted by David Chandler on October 10, 2011

I consider myself more of a tools & frameworks guy than a language geek so I’m more likely to groan than gush over a new language for the Web.

However, as I dug into Dart a bit working on a couple of the samples, I have to say I caught a bit of the same fire that I felt when I first encountered Google App Engine and GWT. Dart is fun. Coming from a GWT / Java background, I found it easy to get started.

Here are a few of my favorite things about Dart so far:

  1. Closures. You can register an event handler as simply as
    element.on.click.add((Event e) { window.alert('You clicked'); });
    Already, I don’t miss the clutter of anonymous inner classes.
  2. Functions can be passed by reference. You can define
    myClickHandler(Event e) { ... }
    and then just write
    button.on.click.add(myClickHandler);
  3. Function type aliases are a compact way to create your own callback types.
  4. Optional typing. At first I thought I wouldn’t like this. However, as the Ruby community has long pointed out, Java is full of redundancy. Why write
    String[] values = new String[] {"a","b","c"};
    when
    values = ['a','b','c'];

    will do?
  5. Getters and setters. If you define methods using the get or set keywords, Dart will invoke them when you reference a field using dot notation. That is, some.property automatically invokes some.getProperty();.
  6. Constructor initializers. If an argument has this. before it in a constructor argument list, the field with that name will automatically be initialized with that argument’s value. So a constructor that simply assigns arguments to fields can be written on one line:
    Point(this.x, this.y);
  7. The Dart DOM and HTML libraries provide convenient and mostly transparent access to the DOM. Thus, you can easily use static layout in an HTML file and call document.getElementById(). The Canvas code in the Sunflower and Spirodraw samples is almost identical to the corresponding Javascript.
  8. document.query(id_or_class) and .queryAll() work very similar to jQuery. These are part of the Dart HTML library, which offers convenient access to the DOM.

Thanks to all the syntactic sugar, Dart code is quite a bit smaller than the corresponding GWT app. My GWT sunflower app required very little modification to run in Dart, and the Dart code for the app went from 96 lines to 58 lines. Better still, I replaced the GWT SliderBar widget (almost 1000 lines of Java) with just a few lines of static HTML (my apologies to Firefox users: FF doesn’t support <input type=”range”> yet). Spirodraw was reduced from ~500 lines to ~300 lines, and the control panel layout is completely static HTML, which makes it easier to read.

Of course, it’s very, very early for Dart. GWT is a mature toolkit with a solid IDE (Google Plugin for Eclipse, among others), mature frameworks for RPC, MVP, etc., and a large open source community. But based on first looks, Dart is a promising new way to write Web apps. If browser vendors implement the Dart VM natively, it will rock! Chrome seems pretty likely to do this, at least. Until then, you can use dartc to produce JS for any modern browser. Hopefully, the editor (demo’d in the GOTO conf keynote this morning) will ship soon and make it easy for everyone to get started with Dart.

See also

Posted in Dart, Google Web Toolkit | 9 Comments »

GWT performance tip: watch out for String.split()

Posted by David Chandler on July 12, 2011

GWT benchmarking inside Google shows that due to intentional emulation of the differences between Java and JS regex, GWT’s emulated implementation of String.split() is about an order of magnitude slower than the native split on all browsers. On Chrome, it can be up to 1000x slower (6000 ms vs. 6 ms) if the strings are large enough (>1 MB in benchmark testing). This isn’t likely to be noticeable in many real-world applications, but if you happen to be doing a lot of String manipulation in GWT, you should consider using JS native methods instead.

Posted in Google Web Toolkit | 1 Comment »

 
Follow

Get every new post delivered to your Inbox.

Join 220 other followers

%d bloggers like this: