Tuesday, January 05, 2010

Why I left GWT and came crawling back to jquery

jquery, I'm sorry I said those mean things about you. After all the good times we had together, I walked away the moment GWT batted its eyes at me.

We got along okay at first, GWT and me. But then I started running into problems with the simplest things due to GWT's convoluted overuse of container markup for things like text and links. Trudging on, I encountered vexing UI layout bugs that could not easily be solved without dissecting that very-same convoluted container markup. When I cracked open the Firebug Inspector, I was shocked to see just how many containers were being created for even the simplest layouts, and that same complexity made it mind-numbingly tedious to comprehend the effects of the CSS on all that markup.

Of course, using Eclipse's superior source-code navigation capabilities, I was able to find the offending source code. It was one of those weird decisions made in a private method 4 superclasses up. (To fork, or not to fork? That is the question.) With the offending code safely barricaded, er, encapsulated, I turned back to hacking the CSS rules on that seemingly unending hierarchy of containers. That was when I first doubted my decision to leave you, jquery... But I trudged on, in search of that beautiful, statically-typed, generic, polymorphic sunrise.

The two faces of GWT-RPC

Okay, so the approach to UI layout is needlessly complex and tedious, but at least there is the beauty of GWT-RPC, right? That's what I thought, until I learned firsthand of the nasty RPC problems that arise when you make assumptions about what objects you can transfer. There are JavaScriptObjects and pojos and a bloodbath of DTOs trying to hold things together.

There was the time I naively assumed that I could read a JavaScriptObject from the "wild" and then pass it upstream in a GWT-RPC call. BZZZTT! Please convert to a pojo and try again.

Then there was the dreaded RPC Types Whitelist thingie that couldn't deal with my clever use of generics. I couldn't find this mythical whitelist file, so I just added dummy methods to my RPC interface referencing all the different concrete types I would need to be able to handle. (Bleh.)

Closures

There was also the misery of recreating in tedious boilerplate Java what is so succint and beautiful in Javascript. Closures become anonymous callback classes with several lines of boilerplate for the interface instantiation and the method declaration. I would agonize about whether to convert to a top-level class, which would then require me to pass in all my closure variables to a constructor and hold them in member variables, and pretty soon the once-elegant javascript closure has exploded into a 100-line .java file of its very own...

Java has a degree of elegance when compared to C++, but not next to Javascript: closures save time. Hip companies like Apple know this. Maybe someday Sun will catch up.

Here's your host.... (loading)

Then there's GWT hosted mode with its slow launch time and its generated code that I can't follow in Firebug because, you know, some-really-smart-guy-that's-probably-smarter-than-me wrote it, and so what right do I have to debug code generated by said-smart-guy's compiler? But then there's this little problem called, I have no idea why my RPC is failing, and why does it have to be this hard? and maybe the GWT-RPC mechanism is just flawed, and maybe I should just dump it and rewrite my own RPC mechanism?

Dump GWT-RPC and rewrite my own RPC mechanism? Not a bad idea....

And so I did.

Using jquery.

JSON, JSOFF

The funny thing is, it was so easy. All I needed was some JSON conversion on the server-side and then your getJSON() method took care of everything else for me. And then finally, I had my Firebug back. And I had my closures back. And no more private methods 4 superclasses up; I had my easy mixins back. And suddenly event-handling was easy again.

I miss a few things from that fling with GWT. The CSS sprites were good (ImageBundle, in GWT parlance). The idea of deferred binding is nice. The focus on performance in general, will be missed. The new native hosted mode is definitely a step up from GWT 1.x. I will miss refactoring, sort of. (It's absolutely essential when dealing with the verbosity of Java, but many of the types of code changes that make refactoring necessary in Java just aren't even necessary in Javascript.)

Still, it's good to be back. It's amazing what you can do in just a few lines with a javascript closure. And I don't mind writing "throwaway javascript code" when it feels good every time.













11 comments:

ZiglioNZ said...

So true...

the same happened to us.
I've come to appreciate JavaScript after experiencing jQuery.
I don't think there's really value yet in hiding the details of Html, Css and JavaScript.
Converting Json to Java is painful, even using native methods.
You can't for example convert a Number to an Integer (but you can convert a numer to an integer).
I've just learned so much about how things really work since we switched from Gwt to jQuery.

Unknown said...

> You can't for example convert a Number to an Integer (but you can convert a numer to an integer).

Ah yes, I struggled with a similar problem, the JSNI autoboxing issue.

ZiglioNZ said...

yep, that was me again who re-raised the issue.
I saw Ray Cromwell in his GQuery had written some clever stuff to do Json to Pojo conversions using native methods

Unknown said...

Yes, Ray has done some incredible things with GWT, and he has given me a healthy respect for the GWT compiler, specifically. I think he understands the tradeoffs between jquery and GWT as well as anyone. As he points out here, "A future refactoring of the compiler could support multiple input languages (like JS2, Groovy, Scala, etc)".

I think a JS2 frontend would be particularly appealing. For "legacy" browsers it would present JS1, and as browsers gain JS2 support, they would just get an optimized, minified form of the original JS2 source.

Unknown said...

One nice thing about GWT is the compiler optimizations you get (inlining, dead code pruning, aggressive renaming, etc.). Well the jquery 1.4 release announcement tipped me off to a new compiler that brings similar optimizations to javascript but with no java necessary.

Dave said...

Yeah, the verbosity of Java / GWT can be a downside when stacked up next to jQuery, but GWT definitely brings benefits to data-driven web application.

Have you worked with the ExtJS GWT (GXT) library? The layout and widgets have a little steeper learning curve than that of vanilla GWT, but in the end it's very nice to work with (especially when dealing with callbacks and event handling)

Unknown said...

@Dave, my concern with GXT is that you have to learn both GWT *and* Ext JS, and neither of them taken alone are simple. On top of that, the advantages of GWT compilation and debugging are muted, if not entirely nullified, by the inclusion of such a large swath of external code.

Not saying it's a bad idea--just not a decision to be taken lightly.

Fraer said...

I'd say comparing to the pros thses are not cons at all, and more, these issues aren't issues you should @Think different :)
And it is treated by using GWT a bit longer. You will love GWT and never want to jquery back.
If you work in the team it will be a hell to maintain all javascript sources, find bugs, subscribed listeners etc. Fix jquery source is it easier than fix GWT source, really? You said many containers were generated...so they all needed if for your case they don't, it means that you've selected componet wrong and you just need write your own component, it's so easy.
There are a lot of great benefits that are absent in jquery and extjs.

Unknown said...

Fraer, fair points: If you are working on a large team where you have to read other people's spaghetti, the constraints imposed by Java will probably make your life easier. GWT makes it harder to write truly bad code (just as it makes it harder to write truly great code).

I doubt my opinion will change "by using GWT a bit longer" as I have used it quite a bit. Using GWT for everything is like leaving your convertible in the garage all the time and driving a bus every day. Live a little!

I for one have moved on to tinkering with cross-browser CSS3.

Wendel said...

Some comments:

UI layout,

It is as simple as you make it. Don't use the standard widgets of GWT, they are old and make to much use of Tables. Instead, make your own components. It is as simple as creating a FlowPanel (div) and enhance it with cool CSS3 features. GWT gives you the tools to animate it and add all kind of handlers.

Don't try to theme the existing components!

GWT-RPC.

Create Action objects with a cargo bay and Response Objects, and a set of Exceptions when something goes wrong.

public interface MainServiceAsync {
public void execute(BasicAction action, AsyncCallback callback);
}

Is the only one method which you need to implement.

I think you utilised GWT the wrong way which left a bad taste..


Unknown said...

Well ... if you're making a widget with javascript, you'll have a bunch of wrapping container too.

I don't think containers is a problem with GWT ... sure HTML, CSS and JQuery are great when you write everything from scratch ... trying modifying a JS widget done by someone else ... You will see as many container as you see in GWT.