TurboManage

David Chandler's Journal of Java Web and Mobile Development

  • David M. Chandler

    Google Cloud Platform Data Engineering Instructor with ROI Training now residing in Colorado with the wife of my youth (31 years). Besides tech, I enjoy aviation and landscape photography.

  • Subscribe

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

    Join 1,120 other subscribers
  • Sleepless Nights…

    May 2024
    S M T W T F S
     1234
    567891011
    12131415161718
    19202122232425
    262728293031  
  • Blog Stats

    • 1,046,321 hits

Archive for the ‘Google Web Toolkit’ Category

Speeding up enterprise GWT development

Posted by David Chandler on May 12, 2015

TL;DR

  • -draftCompile
  • <collapse-all-properties />

GWT developers are always looking for ways to speed up the development cycle. Colin Alworth has written an excellent blog post on GWT compiler options that can be used to select for faster builds or smaller output. In this post, I want to highlight the two most useful options for speeding up GWT development and show how to select them using a maven profile.

Speed up super dev mode (SDM) launch

GWT super dev mode, which is now well integrated in IntelliJ Ultimate Edition and (soon!) Google Plugin for Eclipse, does incremental compilation to bring page refresh time down to a few seconds for most applications. However, the initial compilation can still take a minute or more depending on the size of your app. Typically, about half the time is spent creating any required permutations. Normally, the browser request that triggers initial compilation in super dev mode will include enough information (such as user agent and language) to select a single permutation; however, if your application includes properties that generate additional permutations, you can use a tag in your gwt.xml to collapse them all into a single permutation. Simply include this in your gwt.xml:

<collapse-all-properties />

If you’re currently seeing SDM build multiple permutations, this will likely cut your initial SDM launch time by half.

Speed up full compilation

The <collapse-all-properties /> switch is always useful when doing a full compilation because in this case, the compiler must otherwise build all the permutations. Keep in mind that the resulting output is 15-20% larger than any single permutation would be so this is not recommended for your final production build. However, for a quick development build, it’s very useful.

In addition, when you are doing a development build, you can use the -draftCompile option to get about a 25% reduction in compile time at the expense of less optimized output. For testing or debugging, this is a great tradeoff.

The combination of <collapse-all-properties /> and -draftCompile will normally result in a 60-70% reduction in compile time.

Setting gwt.xml properties for development only

When you are using <collapse-all-properties /> or other techniques such as setting a single user agent in gwt.xml, you don’t want to accidentally leave these options in place when compiling for production. A simple way to avoid this is to create an additional gwt.xml which inherits all properties from the base gwt.xml. Both gwt.xml files should use the rename-to attribute with the same module name. The development-only version should inherit everything from the base module and set or override properties which apply to development only. Here is a simple example from my contactmgr example project:

contactmgr.gwt.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 2.7.0//EN"
        "http://www.gwtproject.org/doctype/2.7.0/gwt-module.dtd">
<module rename-to="contactmgr">
    <!-- Inherit the core Web Toolkit stuff.                        -->
    <inherits name='com.google.gwt.user.User' />
    <!-- Other module inherits                                      -->
    <inherits name="com.google.gwt.i18n.I18N"/>
    <inherits name="com.turbomanage.gwt.Util" />
    <inherits name="com.googlecode.objectify.Objectify" />
    <inherits name="com.google.gwt.place.Place" />
    <inherits name="com.google.gwt.activity.Activity" />
    <inherits name="org.fusesource.restygwt.RestyGWT"/>
    <inherits name="com.google.gwt.logging.Logging"/>
    ...
    <!-- Specify the app entry point class.                         -->
    <entry-point class='com.example.contactmgr.client.ContactManager' />
</module>

contactmgr-dev.gwt.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 2.7.0//EN"
        "http://www.gwtproject.org/doctype/2.7.0/gwt-module.dtd">
<module rename-to="contactmgr">
	<!-- Inherit the core Web Toolkit stuff.                        -->
    <inherits name='com.example.contactmgr.contactmgr' />

    <collapse-all-properties />
</module>

In your IDE, you can then create a run configuration specifically for the -dev.gwt.xml. Using this simple technique, you can continue to manage all your module dependencies and properties in the main gwt.xml while setting development-only properties such as logging switches and <collapse-all-properties /> in a separate file.

Configure IntelliJ to use the dev-only GWT module

Configure IntelliJ to use the dev-only GWT module

In the next section, we’ll look at how to select development options using a maven profile.

Setting development options in a maven project

In a maven project using gwt-maven-plugin, we can build on this technique to set compiler options using a maven profile. In my projects, I set the default gwt-maven-plugin configuration to use -draftCompile and the -dev.gwt.xml. I use a separate release profile to do the slower production build with all permutations, optimization, obfuscation, etc. Here’s a snippet from the contactmgr sample pom.xml showing the technique:

    <build>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>gwt-maven-plugin</artifactId>
                <version>${gwt.version}</version>
                <configuration>
                    <logLevel>INFO</logLevel>
                    <style>${gwt.style}</style>
                    <extraJvmArgs>-Xmx1g -Xms64M</extraJvmArgs>
                    <!-- Doesn't affect super dev mode, only gwt:compile -->
                    <draftCompile>true</draftCompile>
                    <modules>
                        <module>com.example.contactmgr.contactmgr-dev</module>
                        <!-- For GPE -->
                        <module>com.googlecode.mgwt.ui.Animation</module>
                        <module>com.turbomanage.gwt.Util</module>
                    </modules>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <profiles>
        <profile>
            <id>release</id>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.codehaus.mojo</groupId>
                        <artifactId>gwt-maven-plugin</artifactId>
                        <version>${gwt.version}</version>
                        <configuration>
                            <logLevel>INFO</logLevel>
                            <style>OBF</style>
                            <compileReport>true</compileReport>
                            <extraJvmArgs>-Xmx1g -Xms64M</extraJvmArgs>
                            <modules>
                                <module>com.example.contactmgr.contactmgr</module>
                            </modules>
                        </configuration>
                        <executions>
                            <execution>
                                <id>gwtcompile</id>
                                <phase>prepare-package</phase>
                                <goals>
                                    <goal>compile</goal>
                                </goals>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
            <properties>
                <gwt.style>OBFUSCATED</gwt.style>
            </properties>
        </profile>
    </profiles>

Note that the default configuration of gwt-maven-plugin specifies the development-only GWT module (contactmgr-dev) while the release profile specifies the base version. To do a full production build, use mvn -Prelease; otherwise, maven will use -draftCompile and the -dev.gwt.xml to reduce compile time.

If you project is particularly large and you use a continuous integration server like TeamCity or Jenkins, you may want to consider using -draftCompile and <collapse-all-properties /> in your builds for pull requests (commits) so you can get build status quicker. For example, using -draftCompile and <collapse-all-properties />, the GXT Explorer project builds in about 6 minutes vs. 18 minutes. There’s likely no reason why you need to build fully optimized and obfuscated output every time someone submits a code change.

Using these techniques in your enterprise GWT projects should help your team to be more productive in GWT development.

Posted in Google Web Toolkit | 1 Comment »

A good time for GWT

Posted by David Chandler on November 19, 2014

Just a quick note to the let the GWT community know that I’m really pleased to be joining Sencha as Developer Advocate for GXT. This is an exciting time for GWT and I’m glad to be part of it again. A lot of the stuff we’ve been hearing about for the last year is really starting to take shape. My own projects are already benefitting from the much faster super dev mode in GWT 2.7.0-rc1. Thanks to incremental compilation, small changes often take only a second to refresh. JSInterop looks promising and I’m happy to see that several companies continue to invest in GWT, including Google, as evidenced by lots of new stuff in GWT 2.7 and its use in the Google Inbox Web app (which, by the way, looks very promising). Sencha’s Brandon Donnelson has contributed a lot to super dev mode support in Eclipse, and the IntelliJ folks have made it really slick to launch super dev mode in IntelliJ 14. I am told that GXT 4 will have some nifty new stuff, too, but more on that later…

I look forward to seeing you at GWT.create 2015!

Posted in Google Web Toolkit | 3 Comments »

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(&amp;quot;api/user&amp;quot;)
@Produces(MediaType.APPLICATION_JSON)
public class UserDao extends ObjectifyDao&amp;lt;User&amp;gt;
{
    @GET
    @Path(&amp;quot;me&amp;quot;)
    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&amp;lt;T&amp;gt; extends RestService {

    @GET
    @Path(&amp;quot;own&amp;quot;)
    public void getForOwner(MethodCallback&amp;lt;T&amp;gt; callback);

    @GET
    @Path(&amp;quot;get&amp;quot;)
    public void get(@QueryParam(&amp;quot;id&amp;quot;)Long id, MethodCallback&amp;lt;T&amp;gt; callback);

    @GET
    @Path(&amp;quot;all&amp;quot;)
    public void listAll(MethodCallback&amp;lt;ListResponse&amp;lt;T&amp;gt;&amp;gt; callback);

    @POST
    @Path(&amp;quot;save&amp;quot;)
    public void save(T obj, MethodCallback&amp;lt;T&amp;gt; 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(&amp;quot;/api/userPrefs&amp;quot;)
    public interface UserPrefsRestService extends RestApi&amp;lt;UserPrefs&amp;gt; {
        // just in case you missed it, all the CRUD methods are inherited
    }

    private UserPrefs prefs;

    public void loadUserPrefs()
    {
        service.getForOwner(new AppCallback&amp;lt;UserPrefs&amp;gt;() {
            @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. 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&amp;lt;User&amp;gt; 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&amp;lt;T&amp;gt; in a JSON root object.
 */
public class ListWrapper&amp;lt;T&amp;gt; {
    private List&amp;lt;T&amp;gt; list;

    public ListWrapper(List&amp;lt;T&amp;gt; list) {
        this.list = list;
    }
    public List&amp;lt;T&amp;gt; getList() {
        return list;
    }
}

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

    @Path(&amp;quot;all&amp;quot;)
    @GET
    public ListWrapper&amp;lt;Subscription&amp;gt; findAll() {
        User user = AuthFilter.getUser();
        List&amp;lt;Subscription&amp;gt; userAll = this.listByOwner(user);
        return new ListWrapper&amp;lt;Subscription&amp;gt;(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&amp;lt;T&amp;gt; {

    public List&amp;lt;T&amp;gt; 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 | 9 Comments »

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 »