Rounding Error

A few months ago, I ran some performance comparisons of various JavaScript selector engines using Slickspeed. My intent was to validate claims made by the ExtJS team as to why they didn’t use the Sizzle selector engine in Ext Core.

Ext Core has now gone final, so I wanted to re-run my tests. But there was also some news on the browser front: Apple released Safari 4 and Google dropped Chrome 2. Being the geek I am, I had to try them out. My Slickspeed test was the perfect candidate for seeing what Safari 4 and Chrome 2 could do.

In my prior post, I said developers should be bowing at the throne of Google for Chrome and its pack-leading JavaScript performance. That crown has now been abdicated. Safari 4 and Chrome 2 are leaps and bounds ahead of everything else on Slickspeed.

Here are the details on Safari 4:

  • Prototype: – 9ms
  • Dojo: – 3ms
  • JQuery: – 4ms
  • ExtCore: – 19ms
  • Sizzle: – 2ms

safari4

Safari 4 didn’t get along well with SnagIt, so I was only able to capture the bottom of the results output. Here are the results for Chrome 2:

  • Prototype: – 13ms
  • Dojo: – 4ms
  • JQuery: – 2ms
  • ExtCore: – 41ms
  • Sizzle: – 1ms

chrome2

This is simply stupendous. The performance of JQuery turns into a rounding error in both these browsers. As a basis of comparison, here are the prior results for Chrome 1:

  • Prototype: – 13ms
  • Dojo: – 7ms
  • JQuery: – 8ms
  • ExtCore: – 13ms
  • Sizzle: – 8ms

So what conclusions can we draw?

  1. Choice of JavaScript engine becomes irrelevant with any of these two WebKit based browsers. They all fly, even lowly Prototype.
  2. Ext, LLC, screwed the pooch in not using Sizzle for the selector engine in ExtCore. It would have been a better investment in them adopting Sizzle and working to improve it rather than blazing their own trail. The difference in Chrome 2 between Sizzle and ExtCore is staggering: 1ms in Sizzle vs 41ms for ExtCore.
  3. The latest and greatest from Microsoft (IE8) starts to look absolutely pathetic compared to the competition. Microsoft should be ashamed of themselves for having their asses so soundly handed to them on such a critical piece of infrastructure as the browser. Whether it is due to their outdated opinions on open source, or that they can no longer attract top talent, Microsoft is proving to not even be a contender in the JavaScript performance race.
  4. Both Apple and Google use WebKit as the basis for their mobile offerings (iPhone and Android). The sheer power of WebKit is going to offer both these platforms outstanding opportunities for rich browser-based applications. It is clear why neither platform cares much about Flash or Silverlight: the don’t need them.

Slick Speed

One of the big questions that people have had about ExtCore is why didn’t it make use of the Sizzle selector engine. That was one of the questions I wanted to get answered at the Ext Conference last week, and I managed to pin down one of the core developers to get an answer. Their opinion was that Sizzle is too large and too slow. I don’t really care about the size aspect. They all tend to pack down into the 25K range, but I was interested in the speed comment. Like a lot of folks, I was led to believe that Sizzle had a lot of, well, sizzle. So in the interest of getting to the bottom of the story, I did a little unscientific testing of my own using Slickspeed, which tests selector engine performance.

I grabbed the latest of the main libraries: ExtCore (beta1), JQuery 1.3.2, Dojo Core 1.3.0, Prototype 1.6.0.3 and the Sizzle engine by itself. I ran Sizzle by itself because although JQuery uses Sizzle, the version of Sizzle in JQuery 1.3.2 is 0.93 while the current version on the Sizzle website is version 1.0. I used the latest version of Slickspeed and made three runs in IE8, Firefox 3.0.8 and Chrome 1.0.154.3. Yes, I disabled Firebug in Firefox. My dev desktop is a rather beefy Windows Vista 64-bit machine with a quad-core 2.66ghz CPU and 8GB of RAM. I did a complete page refresh between runs to start relatively clean. I was going to relaunch the browser between runs, but it ended up not making much of a difference.

First up was the latest and greatest from Microsoft, Internet Explorer 8.

  • Prototype: 440ms
  • Dojo: 61ms
  • JQuery: 48ms
  • ExtCore: 80ms
  • Sizzle: 46ms

ie8

The image shows the results from the last run. I was actually surprised that IE8 did reasonably well. One thing is clear, friends don’t let friends use Prototype with Internet Explorer.

Firefox was a slightly different story. The selector engine in Prototype still got its clock cleaned, and ExtCore swapped around with JQuery and Sizzle:

  • Prototype: 145ms
  • Dojo: 64ms
  • JQuery: 77ms
  • ExtCore: 49ms
  • Sizzle: 71ms

ff3

It was interesting both Sizzle implementations slow down in Firefox. I would wager that the Sizzle folks made a conscious decision to optimize the core selector engine for the most widely used browser (Internet Explorer). ExtCore leaps ahead with Firefox 3, while Dojo is still pretty consistently finishing in the middle. Oh, and friends don’t let friends use Prototype with Firefox either.

Chrome is an absolutely game-changing stunner of a browser. Based on the selector benchmarks, the developers for all these engines should be offering to have children for the Chrome developers:

  • Prototype: 13ms
  • Dojo: 7ms
  • JQuery: 8ms
  • ExtCore: 13ms
  • Sizzle: 8ms

chrome

Even lowly Prototype with Chrome makes any of the other libraries running in Firefox look like they’re standing still. Chrome is simply ungodly fast with all them. ExtCore could probably still use some tweaking, but we’re talking about a 7ms delta between the fastest and slowest.

So the Ext team’s claims for Sizzle being slower are only partially true. Sizzle appears to be faster in Internet Explorer, while the story flips around in Firefox where ExtCore is faster. All of them, even Prototype, are fast in Chrome. Pray for the day when Chrome takes over the world. Until that time, It looks like all them (Dojo, JQuery/Sizzle, ExtCore) are good in IE and Firefox, with the nod going to JQuery/Sizzle for Internet Explorer, the browser market share leader. And you really, really don’t want to use Prototype until all your clients have moved to a modern browser with native selector engines, or Chrome.

One glaring omission is that I didn’t test with IE7 or IE6. Using either of those browsers is also on my “friends don’t let friends…” list. It would be safe to say that they would both be slower. As I don’t have either installed on any of my computers, I would be happy to add an update for anyone who wants to run the tests themselves.

The Ext team earns some slack in their Internet Explorer performance as they are only a beta compared to the others. I’ll rerun the test again when ExtCore goes GA. And on a final note, here is the config.ini file for Slickspeed in case anyone wants to try the benchmark themselves, or you can grab the whole Slickspeed install with the selector engines configured.

Beyond the Core

In my earlier post, I compared the new Ext Core JavaScript library with JQuery to demonstrate how close they are on core functionality. I explicitly kept the scope narrowed down to areas where the two libraries overlapped, and my conclusion was that both are winners but I prefer Ext Core since I use ExtJS and prefer the coding style.

In this post, I want to get in to demonstrating some of the features of Ext Core that are either coded differently from JQuery or that the base JQuery library does not implement. The excellent Ext.Core manual has more detail on all the functions, so I’ll just bring attention to some of cool functionality I like.

Base Class Enhancements

One feature that might be controversial for some developers is that Ext Core augments some of the base JavaScript objects to ensure some features are present across implementations and to add some useful helper methods. The JavaScript Augmentation section of the manual has details on all the enhanced methods. Function, Array and String are the three base objects that get augmented.

For example, the String object is augmented with a static format() method that essentially allows the String to function like a typical printf function:

var dest = 'World';
var greeting = 'Hello';
var msg = String.format('{0}, {1}!',greeting, dest);
// msg contains "Hello, World!"

The Array object is augmented with indexOf() and remove() methods, and the Function object itself picks up several OO-centric functions.

The reasoning behind the augmentations are in the manual. I have mixed feelings on augmenting the language’s base objects, but the features are appreciated.

Namespaces

Using a namespace mechanism so that all your variables don’t pollute the global namespace is something every JavaScript coder should be doing. There are plenty of code snippets out there to demonstrate how this is done, but Ext Core makes it easy for you by including namespace support as a part of the library. All this is handled through the Ext.namespace() static method.

Take a look at the sample below. The comments indicate the filenames:

// first.js
Ext.namespace('First');
First.name = 'Tim';
 
// second.js
Ext.namespace('Second');
Second.sayHello = function(name) {
    alert( String.format('Hello, {0}',name) );
};
 
// main.js
Ext.onReady(function() {
	Second.sayHello( First.name );
});

The three JavaScript files don’t even need to be imported in this order. Everything happens through the namespace references declared at the tops of the files and managed by Ext Core. In this case, objects called First and Second were created under window, and the sayHello method and ‘name’ variable were placed under them. This means our code only added two variables to the global space. This didn’t make a difference with only two variable declarations, but can have a huge impact with a typical application.

Namespaces can be hierarchical, so you can limit the global pollution to a single entry. For example, you can define a namespace like this:

Ext.namespace('Application.Init');

Ext Core will create all the intermediate namespaces, so you could places variables under both Application.Init and Application with this single declaration. This provides a similar naming hierarchy to what you would find in Java packages or C# namespaces.

Encode and Decode

Ext Core provides helper methods to encode and decode both JSON and URL-encoded data. The Ext.encode and Ext.decode will encode or decode JSON objects to and from Strings. This is useful for the AJAX methods, as I demonstrated in my other post. In the current beta, the encode and decode methods aren’t implemented yet, but they are in the documentation, so I’m expecting to see them before the final release.

The Ext.urlEncode and Ext.urlDecode methods will encode or decode JSON objects to URL-encoded strings. One typical example is to decode query string parameters. For example, if the page URL was this: http://mycoolapp.com?name=Tim&lang=Java, you could easily decode the query string into a JSON object using this snippet:

var params = Ext.decode( document.location.search.substr(1) );
alert( String.format('Hello, {0}', params.name) );

Yes, this is a bit of a hack. I didn’t do error checking to ensure there was a value for search before using substr(). The substr() is necessary when working with a query string because the search value will start with a question mark (?), which the Ext.urlDecode method won’t strip off.

Templates

Ext Core thankfully includes Templates, a feature generously carried down from ExtJS. Templates simplify the repetitive generation of HTML fragments, which is something that typically happens in AJAX intensive web application. The Ext.Template class allows you to define an HTML fragment as a template, using tokens which will be replaced with the values from a JSON object. For example, here is a code sample of a Template used to format an RSS feed from Slashdot that I turned into a JSON object:

// Feed.data is an array of JSON objects that look like this:
// {title: 'title', link: 'link', description: 'description'}
 
var template = new Ext.Template(
            '<div class="story">',
            '<h3><a href="{link}">{title}</a></h3>',
            '{description}',
            '</div>');
 
// stories is the id of the empty div on the page
var stories = Ext.get('stories');
 
Ext.each(Feed.data, function(item) {
    template.append(stories, item);
});

This snippet also demonstrates the Ext.each() helper method for iterating over the contents of an array. You can download the full snippet here to play with.

As Ext Core is still in beta, there is a disconnect between the API documentation and the actual implementation. If the Ext.Template class is updated to correspond to the documentation, there are also some neat formatting effects that can be applied. For example, instead of the placeholder {description}, you could use {description:ellipsis(20)} which will truncate any string longer than 20 characters and place ellipsis at the end of the string.

I’ve covered a few of the cool features to make your JavaScript code easier and more maintainable. Ext Core also has some neat OO functionality that I’ll cover in another post.

Feedback

It has been fun watching the comments on my write-up yesterday about Ext Core on some of the sites it got posted to. It is clear, for some people, discussing JavaScript libraries has drifted into the same hazard zone as discussing religion and politics. While I appreciate all the feedback, and probably should have signed up for adwords before posting, I do want to clarify a few things:

  • GPL – I hate it, deal with it. There are two reasons a library author would use GPL. First, to prevent someone else from monetizing their effort (ala ExtJS), or second, because open source is an agenda and not a license. An altruistic developer who is interested in helping other developers without expectations of a return will use a reuse-friendly open source license for their libraries like Apache or MIT. If you’re trying to change the world, please, go ahead and use GPL. If you just want to help out your fellow developers, use something with no strings attached.
  • ExtJS Haters – still a surprising number of geeks out there who are bitter about the change from LGPL to GPL. I was a vocal critic of the change too. I got over it — I bought a license and no longer care. Best $289 I’ve ever spent. If you’re looking for a free ride, look elsewhere. Ext LLC is for-profit entity and I agree with them. People should be able to put food on the table writing cool code, and I won’t deny the talented developers at Ext LLC that right.
  • Fluff – I especially got a kick out of this. It was the longest blog post I have ever written (1800+ words) and tried to touch on as many areas as I could. I plan on following up with some more detailed posts. Guess you can’t make everyone happy.
  • The Conclusion – JQuery is an awesome library. I’ve used it for years. I’ve also used ExtJS and will now use Ext Core more. Why? For the same reason some developers gravitate to Perl and others to Java — Style. I come from a OO Java background, and thus the coding style of the whole ExtJS/Ext Core duo is more in line with my preferred comfort zone. Both JQuery and Ext Core are awesome libraries. Pick the one that suits your personal style and objectives.

New Kid on the Block

On this cloudy Dallas Saturday morning, the ExtJS team announced the availability of Ext Core (beta). Ext Core is the core DOM selection, manipulation and events library of ExtJS which has been extracted out into a separate library released under a more liberal license. They smartly released this under the very permissive MIT license, in contrast to the cancerous GPL used for the full ExtJS.

What makes this interesting is it positions Ext Core as a direct competitor to the popular JQuery library. I really like both ExtJS and JQuery, so I decided to run a quick comparison of the two libraries to see if Ext Core is up to the task of replacing JQuery in my developer toolbox. Since there is so much overlap between the two, it makes no sense to use both.

Round 1 – Size

Library size of the two is pretty close. The minified version of JQuery runs about 56K, while the minified version of Ext Core weighs in at 75K. The 19K difference might matter for an iPhone application, but even then, I would consider it negligible. Both are pretty small libraries, so we’ll call Round 1 a tie and move on to feature comparison.

Round 2 – Load Event

How each of these libraries works the document ready event is more a matter of style. The JQuery convention is to use the dollar sign ($) for for operations, although you can fall back to using the full name (jQuery). Setting up a ready event in JQuery looks like this:

$(document).ready(function() {
    // do cool stuff
});

Ext Core uses the static Ext class for the same functionality. Like the jQuery object, the Ext object is the heart of Ext Core. Setting up the ready listener in Ext Core looks like this:

Ext.onReady(function() {
    // do cool stuff
});

One big difference is the onReady method can take an additional parameter specifying the scope in which the onReady method should execute. This is not a big deal in most cases, but shows Ext Core’s attention to support object oriented JavaScript. Since I’ve never actually needed to specify the scope, I’ll call this round a tie too.

Round 3 – Selectors

This is the heart of both libraries, and a full comparison could fill a dozen pages. The short story is they both support basically the same set of CSS3 selectors along with some custom enhancements. From looking at the documentation, I couldn’t find any typical use cases that either couldn’t handle. Like the document ready example above, it just comes down to a matter of convention. For example, here is the code from each to add a class to a set of nodes:

// JQuery
$('td.age').addClass('someclass');
 
// Ext Core
Ext.select('td.age').addClass('someclass');

One major style difference between the two is that Ext Core has a tighter focus in handing elements with ids, since that is critical to the full ExtJS library. For example, Ext Core has the get() method to directly grab an element by ID, along with a memory-friendly fly() method. The fly() method does not create a new element wrapper in memory, and instead reuses a single global element object. This can save a lot of memory when you just need to do quick manipulations of single objects.

// Add a class to the element with ID of 'header'
Ext.fly('header').addClass('someclass');

For the memory saving fly operation, I’ll give the advantage to Ext Core, although they are essentially equal in their DOM selection abilities.

Round 4 – Events

Like the selectors above, there are basically style differences between the two libraries in how they handle basic event use cases. JQuery adds some methods to the jQuery object for registering common events. For example, here is the code to add a click event to a button for each, including the JQuery shortcut:

// JQuery with bind()
$('#myButton').bind('click', function() { alert('Clicked');});
// JQuery with shortcut
$('#myButton').click(function() { alert('Clicked');});
// Ext Core
Ext.fly('myButton').on('click', function() { alert('Clicked');};

JQuery brings some some additional enhancements to the game in the form of “live” events. This provides a way of attaching an event to all current, and future, instances of the selector. JQuery also supports event namespaces, where events can be fired in a hierarchy. Both are powerful concepts, but I’ve never had to use either.

The secret sauce for Ext Core is in extended configuration. With Ext Core events, you can also configure the scope (a common Ext Core theme), along with configuring the event propagation, extra parameters, and a delay. Here is a sample of a click event configured with ‘this’ scoped to the onClick event itself, to only fire once (single), with a delay of 100ms and an additional parameter (forumId) to be passed to the event handler:

el.on('click', this.onClick, this, {
    single: true,
    delay: 100,
    forumId: 4
});

So again, I’m going to call this round a tie. Both libraries handle simple event binding very easily. If you need the live events, the nod goes to JQuery. If you need the extra configuration options, Ext Core is your best bet.

Round 5 – DOM Manipulation

Once again, the two libraries provide a near complete overlap of basic DOM manipulation functionality. Each can easily create, move, add and insert DOM elements.

JQuery aims for convenience. For example, one feature of JQuery I really appreciate are simple methods to clear the content of a DOM element and set the text. For example, given:

<div id='message'>First Message</div>

With JQuery, it is simple to update the text:

$('#message').text('New Message');

The text() method removes all the child nodes of the matching elements and appends a text node containing the specified text. The text() method without a parameter will retrieve the text for a matching element. For Ext Core, you have to drop down to the DOM to set the new text value:

Ext.fly('secret').dom.innerHTML = 'New Message';

The Ext.Element class does not provide simple methods for setting the text or removing all the children of an element, which I find to be an annoying inconsistency.

On the plus side, Ext Core provides a lot more methods for manipulating the DOM. One of the cool ones is the radioClass() method. This method will add a class or classes to an element and remove that same class (or classes) from all the siblings. For example, here is a simple table with a row having the ’selected’ class:

<table class="data">
    <thead>
        <tr><th>Name</th><th>Age</th></tr>
    </thead>
    <tr>
        <td>Bill</td><td class="age">20</td>
    </tr>
    <tr class="selected">
        <td>Alice</td><td class="age">21</td>
    </tr>
    <tr>
        <td>Jeff</td><td class="age">22</td>
    </tr>
    <tr>
        <td>Susan</td><td class="age">23</td>
    </tr>
</table>

This one line of Ext Core code will remove the ’selected’ class from the current TR element and add it to the first row in the table:

Ext.select('table tr:first').radioClass('selected');

So for this round, I’ll give the advantage to JQuery for the more consistent API, especially around manipulating the text nodes of an element. This is something pretty simple for Ext Core to address, which they really should. Ext Core does, however, offer more powerful DOM manipulation options.

Round 6 – Effects

I’m not a big effects junkie, so I won’t have a lot to say about this. Both Ext Core and JQuery provide a very similar set of effects for elements (hide/show, fade, slideIn/Out, etc…). Ext Core provide a more powerful API for creating custom effects, while JQuery addresses this with its rather extensive set of plug-ins. I’m calling this one a tie.

Round 7 – AJAX

Ext Core and JQuery both make AJAX simple, but again, we’ll see that JQuery adds more simplified methods while Ext Core offers more powerful configuration. Here is a sample of an AJAX call that returns JSON data:

// URL returns a JSON object like this: {name: 'Tim'}
 
// JQuery 
$.getJSON('http://myurl', function(data) {alert(data.name);});
// Ext Core
Ext.AJAX.request({
    url: 'http://myurl', 
    success: function(response) {
        var data = Ext.decode(response.responseText);
        alert(data.name);
    }
});

JQuery provides the simplified getJSON() method where the parameter to the callback has already been decoded into a JSON object. For Ext Core, the callback receives the XHR response object and you have to decode the text to JSON.

The Ext Core request() method demonstrates a typical ExtJS convention of using a JavaScript configuration object as a parameter instead of using multiple parameters.

Both libraries provide strong AJAX support, so we’ll go with a tie for this round too.

Round 8 – Documentation

There is no contest in the documentation department. While the JQuery documentation has improved, the Ext Core documentation blows it away. From the excellent manual to the high-quality API documentation, Ext Core sets the standard for what all documentation should look like.

Round 9 – Intangibles

For JQuery, the biggest intangibles are its plugins and support from Microsoft. JQuery is intentionally designed to provide a simple core set of functionality and to be easy to extend. There are hundreds of plugins people have written for JQuery in the Plugin Repository. As with all things open source, some are very good and some are kinda crappy, but you can be pretty certain to find a plugin that covers about anything you might be trying to do that is not covered by the core JQuery API.

Microsoft support is also a biggie. They have decided to include JQuery as a base JavaScript library in their web tools going forward. This means you won’t need to get special blessings to use JQuery in large corporate environments — it will be part of the core Microsoft bundle, with support and all.

Ext Core, being brand new, is lacking in both community and support. Ext LLC, the company behind ExtJS and Ext Core is a small software shop trying to get by in a tough economy. While their products are cutting edge, I’m expecting them to be bought out by a larger company before too long. I keep trying to talk my Spring Source contacts into buying them, but I have a feeling they’ll be bought by Adobe.

So from an intangibles perspective, JQuery is the winner. It is guaranteed to have longer legs under it, at least until we see where Ext LLC ends up.

Conclusion

Both Ext Core and JQuery are solid, complete base JavaScript libraries. JQuery leans towards simplicity while Ext Core offers enhanced configuration. The choice of which to use will come down to where you are now.

  • If you use JQuery, and don’t anticipate using ExtJS, stay where you are. You’ve got a winner.
  • If you use ExtJS and have used JQuery as a light weight option for when you didn’t need the widget library, Ext Core is now your library of choice.
  • If you are in search of a JavaScript library, the choice is tougher. Unless there is a particular JQuery plugin you want to use, I recommend going with Ext Core. It starts laying the groundwork for using ExtJS, which you’ll want to do as you get in to building RIAs.
  • If you’re a corporate Microsoft shop, you probably don’t have a choice. JQuery is now something you can slip by the infosec police without making waves.

Ext Core is definitely a winner. In the past, I have used JQuery for projects that need simple DOM manipulation and ExtJS for when I need the widgets, layouts, etc… Now that I have Ext Core, I don’t see using JQuery anymore for the simple cases. I can standardize on using the same API paradigm between Ext Core and ExtJS.

Follow-up #1: Beyond the Core
Follow-up #2: Slick Speed

Springing Around with ExtJS

While playing around more with ExtJS and Spring, I ran in to one of my favorite annoyances — setting up a new project. I can create a new webapp in IDEA (or Eclipse) and add some dependencies, but it is still pretty empty. Maven can go a bit farther, but I don’t like how it handles transitive dependencies. None of these will really give me a good starting point out of the box without either copying a bunch of stuff over from other projects or writing a lot from scratch.

To finally scratch that itch, and move further along the Spring & ExtJS path, I turned my demo project into a basic template. The zip archive that you can grab at the bottom is a fully-configured Spring web application, including Tiles, Spring Security, Spring MVC, custom JSON view, Transactions and a Datasource.

To get started, grab the file, extract it to some directory. Open a shell, navigate to the Template directory and run the ant command ant dist. This will compile the whole project and create a Template.war file in the dist directory. Note, I use Java 6 for all development, so if you’re not at least at Java 5, you won’t be able to use this.

Before you drop the war file into Tomcat’s webapp directory, you’ll need to setup the database. First, copy the jar files in lib/tomcat into Tomcat’s lib directory. This is the MySQL JDBC driver and the JTA files for transactions. You’ll then need to create a new database on your local MySQL instance called tomcat. For simplicity in development, create a user with all rights to the tomcat database. Here’s the code to run from a MySQL shell:

create database tomcat;
use tomcat;
grant all on tomcat.* to tomcat@localhost identified by 'apache';

Your other option is to just put in your MySQL root username and password. To do that, or change the connection string completely, edit context.xml under web/META-INF. If you don’t use MySQL, you will have to edit this file and also put the correct driver in Tomcat’s lib directory.

Once you have the database setup, drop the Template.war file into your Tomcat webapps directory and startup Tomcat. Assuming Tomcat is configured to listen on port 8080, you can open the sample by browsing to http://localhost:8080/Template

The application only has a couple pages. First, the login page:

Login Page

Spring Security is configured to route unauthenticated requests through this page for login. You can take a look at the applicationContext-security.xml file in WEB-INF to see how this was done. There are two users configured for now. User scott with a password of tiger and user bob with a password of password. Yes, not very clever, but it works. Scott is in both the ROLE_ADMIN and ROLE_USER roles, while Bob is only in ROLE_USER.

If you login with scott, you’ll be taken to the index page, which looks like this:

Home Page

The index page simply contains a text box with a button. Entering a message and pressing the button results in an Ajax call to the server which echos the message back to the page. An HTML element in the middle of the page is updated with the result via JavaScript.

You’ll notice in the footer of the page you can see the currently logged in user on the left, and a link to log out on the right. Clicking the log out link takes you to the logout page, which looks like this:

Logout Page

Again, nothing fancy. Just a message saying you have logged out and a link to login again. Use the login link to login as bob and try the echo functionality again. This time you get a different result:

Not an Admin

This demonstrates what happens with Spring Security via annotations. Here’s the echo method in the service layer:

As you can see, the method is secured with an annotation indicating the user must be in the ROLE_ADMIN role to use the method. Bob is only in the ROLE_USER role, so the call to this service fails.

The application makes use of a ResourceBundleMessageSource for the pages mapped through the htmlDispatch servlet. The login.jsp and logout.jsp don’t go through the dispatch servlet, so they can’t use the message bundle for the window and page title.

There is way too much to this simple application to cover completely now, but I’ll give the highlights of what to go look at in the major configuration files. Paths are relative to the project root:

  1. web/WEB-INF/web.xml - notice that I configure two dispatch servlets. One catching *.htm and one *.json. This sets things up to treat Ajax requests differently. Spring Security is also configured here.
  2. web/WEB-INF/applicationContext.xml – typical application context for a Spring application. I turn on annotation handling with package scanning under the sample.core package. Apache Tiles is configured in this file, and I have also configured a Transaction Manager around the JDBC DataSource. You should tweak this based on your underlying persistence preferences. I’m a RowMapper fan, but you can plug in Hibernate or JPA.
  3. web/WEB-INF/htmlDispatch-servlet.xml - the context for web (*.htm) requests. This sets up the ResourceBundle for messages and a typical ViewResolver mapping the *.htm requests to jsp files under web/WEB-INF/jsp. Also configures component scanning for the sample.web package.
  4. web/WEB-INF/jsonDispatch-servlet.xml – the context for Ajax (*.json) requests. Configures component scanning for the sample.json package and specifies a custom Ajax ViewResolver. This will automagically serialize all ModelMaps returned out of the Controller responded to *.json requests to JSON.
  5. web/WEB-INF/applicationContext-security.xml – so simple to look at, yet so painful to figure out. This is the Spring Security configuration file. Although it looks deceptively simple, it was a beating to figure it all out. It enables annotation-driven security, which you saw on the EchoService above. It also sets up the form login and locks down all the pages. Note I leave the /resource directory open. This is where I put all my javascript, stylesheets and images. If you want to secure those resources, you’ll need to get more specific on the intercept-urls.
    Users are declared at the bottom. Passwords are clear text, which is fine for a trivial demo, but you would want to replace this with something more industrial-strength in a real application.
  6. web/WEB-INF/tiles-config.xml – the Apache Tiles configuration. I only setup one definition here to keep it simple.
  7. web/WEB-INF/jsp/layouts/baseLayout.jsp – the base layout used for tiles. I’m only inserting content at two locations in the template. In the HTML head section, I allow for an optional insert of headerContent. I use this to include JavaScripts specific to a page. The other content is within the center div called mainContent.
    Note that the body is pretty empty and that the divs all have the x-hidden class. This means they are not normally visible. I use an ExtJS Viewport for layout, which uses the contents of these divs.
  8. web/resources/javascripts/layout.js – this JavaScript file was included in the baseLayout.jsp above. It creates the Viewport using a border layout.
  9. web/resources/javascripts/index.js – the JavaScript file included for the index.jsp page. It decorates the plain HTML inputs on the page to do the cool Ajax stuff. Note towards the bottom how I use ExtJS to set focus on a form field and to bind the ENTER key to the submit button.
  10. web/resources/javascripts/login.js – the JavaScript file use for the login.jsp page. If you look at login.jsp, you’ll notice there is no form. Everything is created by ExtJS from the login.js file, including the cool box effect. One trick is that Spring Security wants a normal form POST for the login form. I override the form to do a standard submit instead of an Ajax submit and set the form action explicitly.

This covers the major features. I’ll be using this as a base for other projects and will be expanding out my ExtJS demo. Since there are pretty much zero examples out there of tying together this stack, I hope this can be of use to some folks.

Project Template

  • 2/28/2009 – upgrade to ExtJS 2.2.1, fixed compile issue on Linux, added in iBatis for ORM
  • 3/26/2009 – I’ve setup a dev server with the latest version of the template at CodeZombie.com so you can check it out without having to install. User scott/tiger for credentials. I’ll be updating this install with a more feature-rich demo application shortly
  • 3/28/2009 – changed around the project structure and build.xml to use Ivy for dependency management. Check the README.txt file in the root directory for the details.
  • 4/28/2009 – updated the included JSON encoder to be able to return JSON arrays by using the key _root in the model map. If this key is found, its content will be used as the root element of the return JSON instead of encoding the whole map. Also removed the unicode characters from StringScrubber to make the compiler on Linux happy.

p.s. this pulls together a lot of jars and pieces from different folks to build the demo. If you use this for more than playing around, you need to make sure you respect whatever licenses the authors have in place.

2009 Predictions

Not to be outdone by the innumerable quantity of pundits out there making their own baseless predictions, I’m going to toss out my own for the coming year in the technology space:

  1. Sun Microsystems is toast. Their only real asset is Java, and it is worth more to a company like IBM or Oracle. If the frigid economic climate continues, Sun will be purchased by IBM.
  2. Windows 7 will rock. This prediction might get delayed until early 2010 given Microsoft’s track record, but I fully expect Windows 7 to put Microsoft firmly back in the drivers seat. It will make up for past sins and put Apple on the defensive.
  3. Google and Apple turn out to be evil after all. Pretty safe bet; both want to be what Microsoft was last year and will sell their souls to do it.
  4. Microsoft won’t be the evil empire any more. Now that Bill is gone and Ray Ozzie is setting the tone, you’ll see a lot more warmth and geek-friendliness out of Microsoft. Check out Microspotting if you want to catch a glimpse of the new Microsoft.
  5. Oracle will buy Spring Source. This is about the only jewel they’re missing and would be a better investment than BEA was. Unfortunately, it will kill all the enthusiasm around the Spring Framework, thus killing one of the few exciting things left in the Java space.
  6. (Wildcard) Microsoft buys ExtJS. Apple picked SproutCore, so Microsoft needs a good RIA JavaScript library. They’ve put their backing behind JQuery, which is awesome, but it is not in the same league as ExtJS. They could buy ExtJS for a pittance and have one of the best AJAX widget libraries on the market overnight. ExtJS and ASP.NET MVC will be the winning combo.

Yummy…. Crow!

Yes, I will accept I need to eat some crow. I’ve been playing a lot recently with the .NET framework and C#. My PHP mistress got kinda boring. Same-o, same-ol’. I decided to give .NET another whirl because I wanted to port the ExtJS presentation I did for the local Spring users group to .NET. 

Since I hadn’t really gotten in to .NET since v2.0, I got up to date with Visual Studio 2008 and .NET 3.5sp1. I knew I neeeded JSON for my AJAX, so I thought about starting with WCF. But to fully dig in to WCF, I needed to understand the new features in .NET 3.5, so I found some good tutorials on what was new.

I was really blown away with how far .NET has progressed. I’m a big fan of JavaScript, and C# in .NET 3.5 actually starts to look a lot like it. You can declare variables with the var keyword and you have anonymous classes and lambdas. I actually played with LINQ, and I have say I like it a lot. I will humbly eat that crow pie over the trash talking I gave LINQ serveral posts ago.

I’m still not down with the postback model for ASP.NET, but am playing with ASP.NET MVC, which is getting pretty mature in its fifth preview release. It will definitely be the way I head. I just need to sort out the WCF stuff for the JSON/AJAX calls and I’ll be a happy camper.

So in an epic “I will not eat green eggs and ham” kind of way, I’ve decided I really like those green eggs and ham. But it is a lot more like green eggs and crow in this case.

The Future of Browsing

The big news today was about Google Chrome. Chrome is web browser built by Google based on Webkit that is going to be their way of finally killing off Microsoft. They actually created an online comic book to explain why they created Chrome and the technology behind it.

What makes Chrome special compared to Safari or Firefox is their JavaScript VM called V8. The V8 JavaScript engine provides JIT compilation of JavaScript code, so your JavaScript RIA applications run with blazing speed. ExtJS is incredibly fast in Chrome. Another awesome feature is the ability to create a shortcut to a page that actually is an application link. For example, here is Chrome viewing the ExtJS API documentation:

Notice the window decoration with tabs, navigation, etc… Selecting the Create Application Shortcuts option will create a Start Menu, Desktop and/or Quicklaunch shortcut to the page you are viewing. Opening the shortcut opens the page as a pseudo-application, like this:

This creates a kiosk-mode view, without navigation. This web page of documentation is now essentially a standalone application. Google obviously intends Chrome to be the primary client-side hosting environment for its web-based application suite. This is also really good news for folks using JavaScript for RIAs. With the V8 JavaScript VM, you can have JavaScript performance on par with what a plug-in can do, and thus don’t need the plug-ins.

When Chrome goes final, I don’t see why anyone would not want to use it. It is extremely fast, with a clean UI and will completely change peoples perspectives on web-based productivity software. ExtJS becomes stunning in Chrome, and I’d actually bet that Google buys ExtJS to use it as their main JavaScript library. The only question becomes Google motivations. Will they “not be evil” or will Chrome turn into adware/spyware. Time will tell, but I’ll be using it until I think it is evil ;-)

JavaScript at the Speed of Sound

The big news for the JavaScript world today came out of the Firefox development team. They working on a new JIT compiler for SpiderMonkey called TraceMonkey. This is going to have huge implications for building RIAs with JavaScript and will expedite the death of both Flash and Silverlight. Why use a plug-in when you can get this kind of performance in just the browser.

This is all slated for Firefox 3.1, so it is still early, but this, along with development in the Safari Webkit space, are going to make the JavaScript world a very interesting place to be.

More gory details can be found on Andreas Gal’s blog post about it.