-
Get a monthly update on best practices for delivering successful software.
I've been using JsUnit for a while now to do Test Driven Development with OO Javascript. I've been implementing mock objects simply by stubbing out methods and adding in a limited amount of logic, but it's just not the same. So, this past weekend was the time to come up with a port of jMock to Javascript. But before reinventing the wheel, I thought I'd take a look around one more time to see if anyone had beaten me to the punch. Enter JsMock, a Javascript mock objects library that supports Firefox 1.0+, IE6+ and Safari 1.5+.
You can add JsMock into JsUnit tests simply by including the jsmock.js file into your unit test HTML page and adding some mock object code to your tests. An example:
var mockControl = null;
var div = null;
function setUp()
{
mockControl = new MockControl();
div = document.createElement("div");
}
/* Interface we will mock */
function DocWrapper() {};
DocWrapper.prototype = {
byId:function(){},
create:function(){},
appendToBody:function(){}
};
/* Object we will test */
function Hello(docWrapper) { this.docWrapper = docWrapper; };
Hello.prototype = {
displayHello:function(id) {
var elem = this.docWrapper.byId(id);
if (elem == null) {
elem = this.docWrapper.create("div");
elem.id = id;
this.docWrapper.appendToBody(elem);
}
elem.style.fontWeight = 'bold';
}
};
/* tests we will run */
function test_NewElem() {
var mock = mockControl.createMock(DocWrapper);
mock.expect().byId("helloContent").andReturn(null);
mock.expect().create("div").andReturn(div);
mock.expect().appendToBody(div);
var hello = new Hello(mock);
hello.displayHello("helloContent");
try {
mockControl.verify();
}
catch(e)
{
fail("Verify should have passed: " + e);
}
}
function test_ExistingElem() {
var mock = mockControl.createMock(DocWrapper);
mock.expect().byId("helloContent").andReturn(div);
var hello = new Hello(mock);
hello.displayHello("helloContent");
try {
mockControl.verify();
}
catch(e)
{
fail("Verify should have passed: " + e);
}
}
function test_BadOrder() {
var mock = mockControl.createMock(DocWrapper);
mock.expect().create("div").andReturn(div);
mock.expect().byId("helloContent").andReturn(null);
mock.expect().appendToBody(div);
var hello = new Hello(mock);
hello.displayHello("helloContent");
try {
mockControl.verify();
}
catch(e)
{
fail("This will fail: \n" + e);
}
}
In the above example, we stub out an interface for a wrapper for the document object (in Firefox and Safari you can actually mock the document object, but not in IE), mock it out for different scenarios, then put the Hello class through its paces, first when there is no DOM node with id "helloContent" and next when there is one. We don't actually modify the DOM in this case, we just reuse a scratch DIV node that we create in the setup. The last test fails on purpose, just to illustrate how the order of calls matters in JsMock.
The documentation is a little sparse, so you have to work your way through the examples to get the gist of JsMock. Prior knowledge of jMock or EasyMock is definitely helpful. If you never do any OO Javascript or TDD, you won't understand why you need something like JsMock. If you do TDD, have at it. It's just another step in the professionalization of Javascript development.
BTW, this tool was just released in August and updated in the last few days, so the paint is still wet on it. Please consider making bug reports to the authors.
This is a review of Pro Ajax and Java Frameworks by Nathaniel T. Schutta and Ryan Asleson. This book seeks to give the experienced developer of Java web applications the knowledge necessary to add Ajax to their webapps. This is another Ajax book that goes broad rather than deep. Instead of investigating one or two frameworks, it delves into more than a half dozen, both Javascript and Java.
Quick summary: Chapters 2, 3 and 5 are the strongest in the book with useful information on tools, Javascript libraries and enhancing Struts applications with Ajax. The other chapters are not as strong and spend too much time covering old ground.
The book is divided into two parts. Part 1 is an introduction to a variety of Javascript and Java Ajax libraries and frameworks. Part 2 shows how to integrate those libraries and frameworks into existing Java web frameworks such as Struts and JSF. One place that this book differs from other Ajax books is that it doesn't have a chapter introducing the reader to the browser technologies that comprise Ajax. It doesn't dwell on the basics of Javascript, DOM and CSS. It expects you to have already read the Apress books on those topics. Instead, chapter 1 covers what I would call best practices and patterns -- autocomplete, partial page update, draggable DOM.
Part 2, as previously mentioned, builds on what the reader has learned about the preceeding Ajax frameworks and libraries and looks at integrating them into existing non-Ajax web application frameworks.
Summary: As previously mentioned, this book goes broad rather than deep in picking out more than a half dozen frameworks and libraries. Also, the examples throughout the book are little more than snippets, not applications that would demonstrate the development of a full Ajax app. Still, there are a wealth of tool and library tutorials and Ajax conversion best practices in it to make it a valuable reference for anyone looking to enhance a legacy webapp with Ajax.
Just a few bits of news heading into the Thanksgiving Holiday (for non-American readers, this is the holiday where our inlaws try to kill us by overfeeding us and family members take up old feuds with one another while watching American football on TV):

Happy Thanksgiving, everyone. I'm off to enjoy the curried goat and turkey.
Topics: Ajax Frameworks, Echo2
There's a great Blog post over at FontFeed describing the Font faces on the logos of a collection of popular Web 2.0 websites. In the list, they detail the trend setters, as well as those that go against it. This is very informative for a web designer. A good reference...
You can view the list here
This past Thursday, Google released version 1.2 of the Google Web Toolkit (GWT). So what's in this release? Probably the most obvious change is the improved startup times and refreshes. Now the edit-compile-debug cycle is very speedy. Aside from this, what else is in 1.2? Well, lots of bug fixes. Lots and lots of bug fixes.
Even the enhancements look like bug fixes, e.g. Change the text of ListBox item: There is no method to change the text of a an item once it has already been
added, such as listbox.setText(index, newtext).
There are actually four major new features:
A speedier hosted mode is great, as I've already noted, as is support for the Mac and the ability to put anything at all into a Tree widget. The HTTP request module comes from users requests for some more control of the XMLHttpRequest object on the client side. This will make it easier to integrate GWT with existing applications.
I'm filled with curiosity with what is planned for GWT with upcoming releases. I guess that's a key word, "planned." I for one would like to see a nice roadmap for GWT rather than the current vague waffling about. For one, I'd like to see other transport mechanisms supported, such as JSONP. For another, I'd like to see better support for testing with tools such as Selenium.
Topics: Ajax Frameworks, Announcement, Google, GWT
One of the things I really like about ZK is that it has a timer component that you can add or remove from a page in order to enable "async" Ajax events in the application. It's a useful abstraction that hides much of the messiness of async update.
<window title="Timer demo" border="normal"> <label id="now"/><timer id="timer" delay="1000" repeats="true" onTimer="now.setValue(new Date().toString())"/> <separator bar="true"/> <button label="Stops timer" onClick="timer.stop()"/> <button label="Starts timer" onClick="timer.start()"/> </window>
Echo2 also has a facility for performing async updates, but it's much more of a roll your own type of facility. I've been wrestling with how to add a timer component to Echo2.
The basic idea is to override the ApplicationInstance as detailed here to allow adding in periodic update tasks. Next, every time a component is registered or unregistered with the ApplicationInstance -- i.e. added or removed from the component heirarchy -- it is added or removed from the periodic update tasks. Fortunately, there are two Echo2 Component lifecycle methods which look like they will work: init() and dispose(). These get called when components get added or removed from a registered heirarchy.
It would be nice if, beyond these two methods, we had something like Swing's HeirarchyEvent and HeirarchyEventListener that allowed us to pass other kinds of events to a heirarchy. Well, the juices are starting to flow again for me on Echo2. I guess it's time to get back to part 2 of the tutorial series.
Topics: Ajax Components, Ajax Widgets, Echo2
In the deluge of social bookmarking, weather ticker, and notepad applications, it's always nice to see an application come along that isn't a toy. APIlitAx (ugly name, I know) is an alternative interface to the Google AdWords system. It seems to have been developed by some folks at google and has been released on Sourceforge. As an application, it is very different from most of the stuff coming out of Google these days, which seems focused around the GWT technology. This applications doesn't use an existing Javascript framework, i.e. it's all custom Javascript, and uses PHP on the back end to proxy requests to AdWords via the APIlity library (PHP API for AdWords).
The developers have been careful to make the application non-blocking, i.e. you can interact with parts of the interface while another part updates. This is probably an emerging best practice for Ajax apps: don't just make lots of small blocking requests. Design your apps so that you can make small, non-blocking requests.
Topics: Ajax Examples, Google, SOA
If you read good books, when you write, good books will come out of you. -- Natalie Goldberg
I first started fiddling with Open Source software somewhere in the mid to late 80's. I was strictly a download and compile guy at the time, but Unix variants being what they were, I was soon up to my elbows in makefiles and C in order to get the darn things to work. From there it wasn't that big of a leap from hacking around to reading the code, and reading code was a truly mind expanding experience.
Up to that time I had just been reading code from books -- little toy programs designed to illustrate a point rather than for production -- and had not been exposed to all of the idioms and approaches that were out there in the wild. You have to read and write lots of bad code before you write good code. And I did plenty of that, even contributing some code here and there to early Open Source projects. I would often download code just to read, not even to compile and install. At one stage I got really into Literate Programming and wrote several large systems using this Knuth inspired approach to writing human readable code. (I found, however, that few in the business world actually value documentation, especially when the deadline clock is ticking.)
One thing is for certain: I learned an awful lot, both on what to do and not do, from reading all that Open Source code. It expanded my world from just books and the handful of programmers I worked with on a daily basis to a cummunity of hundreds and, later, thousands of talented programmers. I stole their ideas and techniques with ruthless abandon. To this day I still read Java, C# and Javascript code in the hopes of finding new ideas and idioms. I even take my code to bed with me to read it before drifting off to sleep.
One of the areas where books are pretty lousy is OO Javascript. Most of the books will let you know how to create your own classes as well as doing some basic inheritance. But beyond a few toy examples, they won't help you in writing real code. Where to look? The major Javascript libraries -- Prototype, YUI, etc. -- have a variety of approaches to OOP. My own preference is for the style adopted by YUI, very similar to that suggested here, here and here, which allows you to chain constructors. My reasons for preferring this approach? I use an excellent and cheap UML modeling program call Enterprise Architect to generate code from models. A more traditional approach to inheritance like YUI's makes writing code generating templates for EA easier.
YUI's approach is short, but not necessarily simple:
YAHOO.extend = function(subclass, superclass) { var f = function() {}; f.prototype = superclass.prototype; subclass.prototype = new f(); subclass.prototype.constructor = subclass; subclass.superclass = superclass.prototype; if (superclass.prototype.constructor == Object.prototype.constructor) { superclass.prototype.constructor = superclass; }};
The punchline here is that you can now call the superclass methods and constructors from the subclass.
YAHOO.widget.SimpleDialog = function(el, userConfig) { YAHOO.widget.SimpleDialog.superclass.constructor.call(this, el, userConfig);};
YAHOO.extend(YAHOO.widget.SimpleDialog, YAHOO.widget.Dialog);
YAHOO.widget.SimpleDialog.prototype.initDefaultConfig = function() { YAHOO.widget.SimpleDialog.superclass.initDefaultConfig.call(this);
// Add dialog config properties // this.cfg.addProperty("icon", { value:"none", handler:this.configIcon, suppressEvent:true } ); this.cfg.addProperty("text", { value:"", handler:this.configText, suppressEvent:true, supercedes:["icon"] } );};
Prototype, JQuery and company have a somewhat different approach to inheritance. There's no constructor chaining, but there are a few more ways to inheriting behavior. For example, in Prototype 1.4, the extend function copies the properties from a base object to a subclass object:
Object.extend = function(destination, source) { for (property in source) { destination[property] = source[property]; } return destination;}
It's a bit more primitive, but can be chained like so: Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype),...
The Yahoo approach to private versus public instance variables and methods is one of commenting and naming. Private instance members and methods are prefixed with a '_' except when they are not. In either case they are commented so as to identify whether the member or method is private or public. Dojo, on the other hand, makes some use of closures and inner functions to enforce the whole public/private thing (see Douglas Crockford's post on this).
One thing that is common to just about all of these frameworks is excellent documentation. Have a dynamic language like Javascript without strong typing and heavy use of idioms puts the burden on the developer to document the code, e.g. from Dojo dojo.io.setIFrameSrc = function(/*DOMNode*/ iframe, /*String*/ src, /*Boolean*/ replace).... I'm looking forward to Javascript 2 with it's support of real classes.
This just scratches the surface of what these various frameworks have to offer. Read code, make notes, save snippets, and improve your own code.
Topics: Ajax Development, Best Practices
As you know, I don't really like to be a blog echo chamber. One post spawns hundreds of "check this out" links, but I suppose that's how I get some of my traffic, so maybe I shouldn't be such a fuddy duddy. But I'll still try to keep it to just those posts I think are worthwhile.
OK, so Web 2.0 is one of those frothy subjects -- even frothier than Ajax -- that spawns all sorts of overhyped, frothy posts and articles. Dion Hinchcliffe is a thoughtful and frequent exception to this rule. He's been posting on the subject on his Web 2.0 blog for over a year now and his latest post, The Habits of Highly Effective Web 2.0 Sites is particularly interesting.
Dion points out seven (is this coincidence?) characteristics of an effective Web 2.0 site:
- Ease of Use
- Open up your data
- Aggressively add feedback loops to everything
- Continuous release cycles
- Make your users part of your software
- Turn your applications into platforms
- Don't create social communities just to have them
I think the first -- ease of use -- is clearly a winner. That is where Ajax can and does play a part. The fifth characteristic is at the heart of Web 2.0, the creation of social networks. More needs to be said on this point, especially when it comes to the Free Rider Problem. If you haven't read much about Communism and the reasons for it's demise, don't worry. If you've experienced the problem of spam on social bookmarking sites -- individuals who get a "free ride" on the work of others by selfishly posting links of dubious quality -- then you know what I mean.
A number of studies have been done on the free rider problem and it's relationship to the size of social networks. All of this research can be used to devise some technical solutions to social bookmarking spam. More on this later.
A few weeks back I put together a post on Agile, Ajax and Offshoring. Martin Fowler, a giant in OO and Agile circles, has some thoughts on Agile and Offshoring as well. We agree on quite a number of things, such as establishing a project Wiki and the primacy of communication. Also, he emphasizes the importance of unit and system tests in formalizing the communication of requirements.
I particularly like his suggestions for running the Iteration Planning Meeting (IPM):
Before the IPM the US customer sends narratives for each scheduled feature (story) which we like to turn into test scripts before the IPM. During this period any questions are handled by email. Just before the IPM the development team breaks the features down into finer grained tasks. These task breakdowns are shared with the US for feedback.
All of this pre-work shortens the phone call which now concentrates on any issues that come up from the task breakdown. We find the calls usually last around a half to a couple of hours. It is important to keep the actual phone meeting short, as these kinds of remote meetings are particularly arduous.
As far as I'm concerned, there are two kinds of meetings: useless and dangerous. Useless meetings are the ones where no information is exchanged, not action items are identified and no assignments and due dates are made. These types of meetings happen with surprising frequency in organizations both large and small. Dangerous meetings are those that run long, and uncover lots of new requirements, issues, and scope. Controlling these dangerous meetings is key to delivering the project, and having people come into project prepared and focused is key. Go now and read Fowler.
Topics: Agile Development
It's already been reported elsewhere, but Adobe has just contributed source code for their AVM2 -- basically a virtual machine for executing ECMAScript -- to the Mozilla Foundation. The project is code named Tamarin, and there are already a number of misconceptions about it. First, it is not an open sourcing of Flash. Rather, it is just the piece that executes the Javascript. Firefox already has a piece that does this, code named SpiderMonkey. The idea is that Firefox and the other Mozilla products that make use of SpiderMonkey will have the goodness of Tamarin swapped or folded in. (See Brendan Eich's post on Tamarin for more details.)
Why is this good news? Well, having the Mozilla and Adobe folks collaborate on a core technology frees them up for doing other, more interesting work. Also, sharing an implementation between two big players strengthens the standard. And let's not forget that that there are lots of cool features in the AVM2 (Actionscript Virtual Machine). SpiderMonkey is an interpreter of Javascript. Tamarin compiles to byte code for a virtual machine which can then take advantage of Just in time compilation (JIT) ala the JVM. The performance of Javascript in Firefox 3 (I hope) will blow the doors off of the current version. Hopefully the improvements will also find their way into Rhino, the Java version of SpiderMonkey (or is SpiderMonkey the C version of Rhino?).
Topics: Firefox, Flash, Javascript
At a quiet time during my 40th birthday extravaganza, I finally had the chance to finish reading Practical Ajax Projects with Java Technology by Frank Zammetti from Apress. I've read enough good, hands-on Apress books by now to get a warm and fuzzy feeling anytime I see their distinctive bumble bee black and yellow covers, so I came to this volume hoping to find an Ajax treatment in that mold. The result isn't an unqualified success in that regard -- it goes broad rather than deep -- but if you're an experienced Java developer looking to get caught up on some of the Ajax developments of the last year and a half, this book is for you.
The book assumes a good foundation in server-side Java development, but little or no experience with the technologies that make up Ajax. Part 1 of the book, which is comprised of Chapters 1-3, is an excellent review of Ajax technology and architecture along with a basic review of Java webapp development. Part 2 consists of seven chapters, each of which develops an Ajax application.
MySubclass.prototype = MySuperclass.prototype should really be something like MySubclass.prototype = new MySuperclass() so that modifications to the subclass's prototype don't affect the superclass. Otherwise, both the superclass and subclass inherit from the same prototype and are siblings rather than parent-child. But beyond this small technical oversight, the chapter is quite strong.As we said previously, part 2 consists of seven chapters, each of which develops an Ajax application. Each application makes use of a different Ajax framework or toolkit, so the treatment of each is not particularly deep. One other curious thing about the examples is that the last two don't make use of frameworks while the first five do. This seems a bit backwards to me, since frameworks provide a level of abstraction over the underlying technology which hides its workings. As a result, you end up not understanding the why and how of how it works. I would have started with simpler projects in the first two chapters that made no use of frameworks, going on to higher level of abstraction as we moved along.
Throughout the book, DTO, DAO and other classic Java webapp patterns are used and extended to work with Ajax and client-side Javascript. For those who haven't used Spring or some of the other open source Java libraries demonstrated in these applications, there is even some non-Ajax learning involved. Zammetti's writing is clear and to the point and his humor doesn't get in the way of reader understanding.
My main issue with the book -- a lack of depth -- is really more a problem with Ajax itself and the proliferation of frameworks. In truth, despite its depth, the book barely scratches the surface of what's out there now in terms of frameworks. The great pace of development means that since this book was put to bed, probably in the third quarter of 2006, several of the frameworks used in the chapters, such as Dojo and Prototype, have seen one or more releases. Still, this is a problem any Ajax book that references frameworks will have to deal with. Despite these shortcomings, I recommend this book to any Java developer who is looking to "learn by doing" with Ajax.
Topics: Ajax Applications, Books
A local school recently asked me to teach a course in Multimedia. It is a first year grad course for people with little design context. Ordinarily I would have been interested in the school and it’s excellent program, yet I stumbled when I heard the term. Living in our Ajax enriched environment it struck me as an old school term, and wondered why it had faded from use.
After a bit of pondering, I came to the conclusion that it is a bit like carving trees out of wood. The metaphor is reversed. The soul in what we do is the interaction; multimedia is occaisionally part of the vessel.
Multimedia means Flash, cheesy little director games, tiny choppy video. Think of children’s CD-roms where low rent repitition is sort of a crash test stand-in for learning cognition. Multimedia means things that are difficult to sell and typically bring dissappointing responses when you do. And not usually worth producing except for massive media clients as they are expensive and cumbersome to update. These are not positive associations.
What is interesting is interaction design and the ability to synthesize actions and events into tighter groupings, both conceptually & physically - ideas like direct manipulation, contextual logic and coherent paths have utility; making it blink is just not that important.
I thought about for a bit, and realized that the suit didn’t fit. Back on the rack.
Topics: Best Practices, Design, Interaction Design, Usability, uxd
Say you're a big company and you've invested heavily in Java Applets as your RIA solution. Java is healthy, developers are plentiful, and life is good, right? Well, no, not exactly. There are still many things to worry about. While Java is still going great guns on the server, it's future in the browser is much less certain. Sun will continue to make sure that Java runs on Vista and it's successors and is as easy to install as possible, but it's clear that Microsoft's unbundling of the JVM started a slow but inevitable decline in Java penetration on the browser. These days, Flash is a better bet if you want a non-Ajax RIA on the browser.
So, if you are said Big company, what are you to do? You have a significant investment in Java and in a code base that works. You do business all over the world and have worked out issues such as internationalization and security. Switching to a technology like Ajax, which seems to splay your business logic into the browser for everyone to see, and has a bewildering set of platform-version-OS combinations for you to support, must be a frightening prospect to a product manager. Also, are you going to have to retrain your developers to work in Javascript and Java? Adding languages and environments adds cognitive stress and makes your development slower and more error prone.
If you can convince yourself that Ajax has all the features and capabilities you need, you are still faced with a choice of Ajax framework. This is a hard choice, and there are no easy answers. It partly depends on your long term IT and business strategy, so making generalizations on which framework is appropriate is a little dangerous, but I'll give it a shot.
If you can afford to wait a bit, I'd suggest putting a little bit of money into exploring GWT and see what develops. Then in six months to a year, you and GWT may both be ready to take the plunge.
Topics: Ajax Applications
idiomatic
-adjective
- peculiar to or characteristic of a particular language or dialect.
- containing or using many idioms.
- having a distinct style or character, esp. in the arts: idiomatic writing; an idiomatic composer.
I finally listened to the Java Posse Podcast #088 last night. It's mostly Bruce Johnson doing the talking, which is fine. Robert and Ryan are smart guys with interesting things to say, but for the pure poop on GWT, Bruce is the man. Lots of interesting topics were discussed, including how GWT builds into a monolithic application that loads all at once. There's work underway in the developer community to support dynamic loading so that as applications get bigger, they can be dynamically loaded.
The most interesting aspect of the discussion, however, was the bit where Bruce Johnson explained why GWT came about. I had originally thought that Google just couldn't find enough qualified Javascript programmers and made lemonade out of lemons. Instead, Bruce said that the larger the Javascript/Ajax project in terms of code and especially programmers, the more complex and unwieldy the project became. I think he use term "idiomatic" to describe the problem with dynamically typed languages, and complained that good tools were hard to build because of the halting problem.
Now I understand what he means by invoking the halting problem. Unlike in statically typed languages, the creation of new types in a language like Javascript is part of the execution of a program. In a worst case scenario, you'd have to execute through the whole code in all of it's possibilities to get all of the possible type definitions. The program might in fact run forever, in which case your nice code completion logic will simply hang. And because of the halting problem (if you can determine whether a program halts, write a program that reads a program, and, if it halts, loops forever, but if it loops forever, halts. Then feed this program to itself.) you can't tell if a particular program actually runs forever or not, so there is no way to avoid the hang. All very tragic.
There are some ways around these issues. You can use heuristics, like the Aptana plugin for Eclipse, to take a stab at the types, or you can agree to write your type definitions in a particular way -- or idiom -- so they can be easily identified and parsed, but writing tools that rely on identifying types in your programs will always be a little harder to write for dynamically typed languages. And tools can be an important crutch, especially if the abilities of your developers are somewhat uneven. A good IDE can suggest or even enforce some rudimentary best practices.
But code completion and tools are a bit of a red herring here. I've always felt uncomfortable with programming languages that depend on good programmer behavior -- essentially obeying code level idioms -- to allow for the development of large, interdependent systems. Alex Russell, in my interview with him, argued that Javascript was a "more powerful" language than Java and cited this paper by Lutz Prechelt that claimed to show that scripting languages are moe powerful and productive than the statically typed, OO languages (in part -- it's a simplification of the thesis). I agree that I can do in 1 hour in Perl what it would take me 10 hours in Java. I might even hope, as a single developer writing my own well understood style of OO Perl, to write a large application more quickly in Perl than in Java. But add in multiple developers, and you start to enjoy the complexity problem that Bruce Johnson mentioned. The same, in spades, goes for Javascript.
In software engineering we implicitly assume there is a continuum of developer skill. The great developers are highly productive, the less skilled ones less so. I would argue that less skilled developers in a team environment are actually destructive -- i.e. they cause more work for other developers. I would further argue that the productivity curve for a language like Javascript is different than that for a statically typed language like Java. I have no data to back this up, but my impression is that the Java skill vs productivity plot is closer to linear, while the Javascript plot is more like a second order polynomial.
My experience with various dynamically typed languages, not the least of which was the horrible mess of OScript in Opentext Livelink -- a rogue dialect of Smalltalk and the Template method pattern gone horribly, horribly wrong, leads me to the conclusion that unless you have some really top flight Javascript developers on hand, you should try to keep your projects small and free of dependencies.
I'm sure this is not the last salvo in the battle between statically and dynamically typed languages, or OO vs Functional, but that's fine. My motto is "the right tool for the right job." And that tool may be Javascript, or Java or something else from time to time.
Topics: Ajax Frameworks, Google, GWT