Wednesday, March 21, 2007

Google Web Toolkit and Firebug

Today I was working on a small web application that uses the Google Web Toolkit. I think a lot of the appeal of GWT is that Java developers have distaste for JavaScript. So what do they do? They build a framework to generate all the ugly JS for them.

I like JavaScript, and I'm not worried that saying so will cause me to take a pay-cut. I have some tools I like to use to deal with it. One is a bookmarklet I found for viewing XMLHttpRequests and responses. It works really well in Internet Explorer 7.

I was playing with my little app on IE, and decided to open up my bookmarklet to see exactly what the GWT-generated JavaScript sent to the server. What did I see? Nothing at all...

Ok, time to get serious. I switched over to Firefox, where I have every web developer's best friend, Firebug, installed. I flipped the switch on Firebug and repeated the same process. What did I see here? Again nothing. Nada.

What the heck was going on? I see the request hitting the server and the response causing the data on the page to be changed. Yet somehow these common debugging tools were oblivious to what was going on. Was there an inviso-IFrame being used? That would be so Web 1.0-ish.

I probed around with Firebug, and indeed there was a massive hidden IFrame on my page. I opened it up and saw that there was a GWT-generated HTML page that was being dumped in here. That page contained tons of JavaScript. And not just any JavaScript, but amazingly obfuscated JavaScript. Here's a sample of it:

function gX(hX,iX){hX.aX = iX;}
function jX(kX){return kX.cX;}
function lX(mX,nX){mX.cX = nX;}
function oX(pX){return pX.bX;}
function qX(rX,sX){rX.bX = sX;}
function tX(uX,vX){;uX.cq(jX(vX));;}
function wX(xX,yX){gX(yX,;lX(yX,xX.Ep());qX(yX,;}

I don't know what to say about this stuff, but it's not the point. This wacky IFrame was where all the magic happened. It's the use of this IFrame and its Skynet-like JS that allows the GWT guys to claim:
Your GWT applications automatically support IE, Firefox, Mozilla, Safari, and Opera with no browser detection or special-casing within your code in most cases.

They're not using the sexiest flavor of AJAX, they're using the lowest-common-denominator version of it.


Anonymous said...

you shouldn't write log post about things you don't know..

dobes said...

I think what he's getting at is that the javascript code generated by GWT isn't obfuscated so much as compressed. This allows the GWT code to load and run more quickly.

You can tell GWT to generate more beautiful javascript, if you want to, although if you're programming in GWT you usually have no reason to look at the javascript anyway. The whole point of GWT is that you don't have write your own javascript.

GWT supports multiple browsers using a different trick - it generates a different version of the javascript for each browser. If you poke around some more, you'll see some code that selects a different javascript file based on the browser you're using.

When writing your GWT code, you can get GWT to instantiate a particular subclass depending on the browser, which makes cross-browser coding a lot easier.

Anyway, hopefully that'll make it clearer what's going on.

Michael said...

I'm not one to split hairs too much, but to quote from Wikipedia:

"Obfuscated code is source code that is (usually intentionally) very hard or ambiguous to read and understand with extraneous information."

The examples I put in the original post were from GWT code. One of the examples:

function tX(uX,vX){;uX.cq(jX(vX));;}

Thats looks "very hard or ambiguous" to read to me. The gratuitous use of the letter X as a suffix for variables and functions seems kind of like "extraneous information" and seems quite intentional.

Now the other common thing done with JS is to minify it. Again from Wikipedia:

"Minify, in computer programming languages, is the process of removing all unnecessary characters from source code, without changing its functionality."

We do this a lot at eBay. Now the code example I gave could be purely minification. The line blurs between minifcation and obfuscation.

VitaminX said...

Read first.
Blog later.