Tapestry Training -- From The Source

Let me help you get your team up to speed in Tapestry ... fast. Visit howardlewisship.com for details on training, mentoring and support!

Tuesday, March 31, 2009

Reducing the size of a Ubuntu VMWare image

I've been building out my VMWare Ubuntu image, the one I use for Tapestry training, and have found that the size has grown out of control. Although inside the VM, my image is only using about 4G, the size of the VMWare folder was well over 8G, too large to fit on the 8G USB flash drives I use to distribute the image.

The solution is time consuming but not difficult; you need to have VMWare Tools installed in the image. If you run VMWare Tools as root (i.e., sudo vmware-toolbox), you can select the primary partition and shrink it. First, many minutes go by as the partition is prepared ... then you are asked if you want to shrink it. Many more minutes go by. At the end, the image is reduced in size significantly ... in my case, to 5.8G total, well within my limit.

Saturday, March 28, 2009

Installing Subversion 1.5 binaries in Ubuntu 8.04

I'm a little left in the lurch currently, because I need Subversion 1.5 client binaries in my Ubuntu 8.04 virtual machine (the one I use for training). This is because Eclipse check projects out in such with 1.5 compatibility (IDEA is kind enough to ask which version to use). In any case, since setting up my Tapestry Workspace involves a bit of command-line SVN, I found myself needing to upgrade SVN to 1.5.

With a little hunting around and some guesswork, I found the solution.

You need to add a new Software Sources location; this is a tool, "Software Sources" inside the Applications > System menu. Click the tab labeled "Third Party Tools" and add a new source. You'll be prompted to enter an "apt-get line": deb http://archive.ubuntu.com/ubuntu/ intrepid main

From there, go into Synaptic Package Manager. Find package "subversion" and you'll see that there's a version of 1.5 now available, thanks to the new software source. You can right click and select "Upgrade", then apply the changes.

Friday, March 27, 2009

Another bad day with Maven

Another bad day with Maven ... first, something changed in the Maven Archetype plugin, so now my archetypes don't work anymore ... and I'm far from the only person with this problem.

Second, I thought I'd use mvn eclipse:eclipse instead of my Ruby script to keep my Eclipse .classpath file up to date: but it doesn't seem to want to download and connect the Tapestry Java sources. So back to the script it is.

Thursday, March 26, 2009


Nope, that's not a date. 1819 is the current number of individual tests run every time a change is committed to Tapestry. Over 180 of those are Selenium-based integration tests. That's a lot of testing!


I'm in the process of creating the Tapestry release, to be voted on. I think will ultimately be the beta release for 5.1, and possibly the final release. The goal is to have a significant upgrade of Tapestry 5.0 that is backwards compatible* to 5.0 but offers great improvements in speed, improved components and Ajax capabilities, and improved localization support (especially on the client side).

Release Notes - Tapestry 5 - Version


  • [TAP5-39] - Add JSON support for literals (often, inline function definitions) that are used to configure some client-side objects (even if they aren't truly JSON)
  • [TAP5-573] - NullPointerException during AJAX form submit
  • [TAP5-578] - If a component class is abstract, trying to instantiate it (by including it in a template) yields an inscrutable InstantiationError
  • [TAP5-590] - A JavaScript error for non-required fields will force Ajax form submits to be handled as a full-page request instead
  • [TAP5-593] - Calling ApplicationStateManager.exists() will throw an exception when the session has been invalidated
  • [TAP5-598] - Hard-coded messages inside tapestry.js are not localized
  • [TAP5-600] - The new Blackbird console makes Safari JavaScript completely non-functional


  • [TAP5-265] - Add a Hidden component, used to synchronize a value between the server and the client
  • [TAP5-398] - Tapestry should check that the service scope is consistent with the service (throwing an exception if the scope requires a service interface and the service doesn't provide one)
  • [TAP5-566] - TextField documentation should explain why the required value parameter is not bound in the example
  • [TAP5-581] - Quickstart archetype should include testng.xml and webdefault.xml
  • [TAP5-584] - Omit generator meta (from head element) when root element is not html
  • [TAP5-586] - The JavaScript waitForPage() handler does not need to be added when rendering a partial Ajax response
  • [TAP5-589] - Add a method to DOM Element class to allow the collection of Attributes to be obtained
  • [TAP5-591] - FAQ: Creating a page render Link from a service
  • [TAP5-605] - There should be a simple way to override automatic JavaScript libraries and Stylesheets

New Feature

  • [TAP5-288] - Replace JavaScript client-side logging with Blackbird
  • [TAP5-549] - JavaScript libraries should be combined into a single request
  • [TAP5-557] - Provide support for URL rewriting
  • [TAP5-562] - tapestry-hibernate should provide a built-in status page to show basic Hibernate statistics inlcuding cache hits, etc.
  • [TAP5-594] - Add simple PageRenderLinkSource service to allow services to create Links to pages


  • [TAP5-510] - Improve code coverage of JSON unit tests
  • [TAP5-575] - Add svn:eol-style=native to source files

My plans for 5.2 are to finally get the Spring Web Flow and Portlet support in, along with the "skinning" component I've been thinking about. And to continue to make upgrading from release to release as painless as possible ... and to do it fast, just another couple of months from whenever 5.1 goes out.

Wednesday, March 25, 2009

Tapestry and Blackbird

Just finished integrating the nifty Blackbird JavaScript console into Tapestry. This will make debugging Tapestry applications much more pleasant, especially under IE (which doesn't have FireBug).

Monday, March 23, 2009

Combining JavaScript Libraries

I've been continuing to do work on speeding up Tapestry performance; I think part of the Tapestry message is not just how easy it is to get started, but how the framework grows with you as your application, and your user base, grows.

One aspect of performance is speeding up server side operations, and Tapestry 5.1 has gone a long way down that path. However, there's only so far that can take you, especially since the lion's share of server-side time is spent waiting for database queries.

Another approach is to minimize both the number of requests and the size of the replies. Tapestry 5.1 will GZIP compress replies for dynamic page content and static asset files. That reduces the size of each reply (when the client supports GZIP compression, which all modern browsers do).

What about reducing the number of requests? As with all web applications, the HTML for the page is just the start: there's also requests for images, stylesheets and JavaScript libraries. Tapestry is already good at giving these resources version-numbered URLs and far future expires headers, so that the client browser can cache them aggressively.

Tapestry 5.1 now adds a feature to combine JavaScript libraries. Whatever JavaScript libraries are requested by components when the page renders are combined into a virtual asset: a URL that represents the combination of the individual JavaScript libraries. This virtual asset has an odd URL (there's some Base64 encoded data as part of the file name), but it also has a far-future expires header and may be served to the client GZIP compressed.

This helps a lot with first-time access to an application; page rendering is interrupted only long enough to download a single JavaScript resource, rather than a series of requests for the individual files. Given that JavaScript must be loaded, parsed and executed serially ... and that rendering of the page is on hold until that occurs, combining JavaScript in this way is a pretty big win, especially given the amount of server-side and client-side caching involved.

The best part is, like many features in Tapestry, there's no configuration to worry about. It just works, it's free, there's no special scripts or tasks to run as part of your build. Better yet, it defaults to off for development mode and defaults on for production mode.

Next release, we may try to minimize the JavaScript as well as compress it; minimizing means stripping out comments and unnecessary whitespace and shortening variable and function names. Again, this would happen on-the-fly.

Monday, March 16, 2009

Announcing TapX: Tapestry Extensions

I've set up a new project on Tapestry360 called tapx (Tapestry Extensions). This is where I can put code that can't live at Apache (due to licensing problems).

The first module is a DHTML calendar component, a wrapper around Dynarch Calendar, an LGPL calendar widget. I consider it the "Cadillac" of this space, and it snaps into Tapestry quite nicely.

Just dropping this new JAR into the classpath not only makes the new DateField available, but also enables it as the default date editor when using BeanEditForm.

The library requires Tapestry or better.

I expect to add many small utlilities here.

Tuesday, March 10, 2009

Clojure at OSCON

Just got the word that my Clojure session has been accepted for OSCON 2009. Covering the language in so little time is going to be quite the challenge!

Monday, March 09, 2009