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!

Thursday, January 12, 2006

Subclipse new project tricks

I go through a little rigamarole every time I start a new project in Eclipse; I use a Subversion repository (locally, or on Apache, or on JavaForge) and I use the Subclipse plugin.

Subclipse is nice, but weakest on the things you do least often, such as creating a project.

I always start in the SVN Navigator; I create my new folder for my project.

I then share the project; I chose the "Use specified folder name". Next, I hit the browse button and select the folder I just created in the navigator.

Back to the Share Project dialog; the cursor will be in the folder name field, and the text "New Folder" will be selected, ready for me to type "trunk".

When I hit OK, we switch over the a synchronize dialog to do the initial checkin. The bin folder will be in the list of resources to check in ... simply uncheck it for now. Then hit OK to check everything else in.

Because you didn't check in the bin folder, your project will appear dirty. That's OK. Now comes the real trick:

  • Execute a "Replace With Latest" (not an update) on your project.
  • Close and Re-Open your project (to get rid of the .svn folder that shouldn't be displayed, but is)
  • Now, use the Team > Add to svn:ignore context menu item on the bind folder
  • Finally, check in your changes (which will appear to be a change just to the project folder itself ... that's where svn:ignore data lives)

Why is this necessary? Somehow during the initial check in, the local project gets out of synch with the repository. I know not what or why, but it's been very consistent against every repository I use, so I think it is a Subclipse problem. If you don't do the replace with latest trick, you will get incredibly annoying SVN errors when you try to mark bin to be ignored ... you just won't be able to check in your project.

Maven and missing Java Transaction API JAR

I'm starting to work on a new demo for Tapestry 4.0 that will be based on Hibernate3, and I want to build on Maven. Of course, the first thing that happened is that I tried to have Maven resolve the dependencies and it tripped over the JAR for the Java Transaction API.

Now, a little background. The JTA is under some Sun license that keeps it from being distributed; so Maven has the POM for it in the central repository, but doesn't store the JAR file itself. So what do you do?

You have to get the JAR file yourself, and convince Maven to load it into your local repository.

Not that Sun makes it easy for you ... oh no. You have to click through a license agreement, then you get the class files, packaged as a ZIP file. This is insane! You'd think they would know what a JAR file is! Why not package the JAR inside the ZIP, maybe with a license and some documentation? Because that would make sense.

I suppose you could just rename the jta-1.0.1B.zip to jta-1.0.1B.jar and go from there. I chose to build a proper JAR first. I started by unpacking into a local directory, then used the jar command as normal:

bash-3.00$ ls -lag
total 0
drwx------+  3 None 0 Jan 12 18:27 ./
drwx------+ 22 None 0 Jan 12 18:27 ../
drwx------+  3 None 0 Jan 12 18:27 javax/
bash-3.00$ jar cf ../jta-1.0.1B.jar *
bash-3.00$ cd ..
bash-3.00$ jar tf jta-1.0.1B.jar
META-INF/
META-INF/MANIFEST.MF
javax/
javax/transaction/
javax/transaction/HeuristicCommitException.class
javax/transaction/HeuristicMixedException.class
javax/transaction/HeuristicRollbackException.class
javax/transaction/InvalidTransactionException.class
javax/transaction/NotSupportedException.class
javax/transaction/RollbackException.class
javax/transaction/Status.class
javax/transaction/Synchronization.class
javax/transaction/SystemException.class
javax/transaction/Transaction.class
javax/transaction/TransactionManager.class
javax/transaction/TransactionRequiredException.class
javax/transaction/TransactionRolledbackException.class
javax/transaction/UserTransaction.class
javax/transaction/xa/
javax/transaction/xa/XAException.class
javax/transaction/xa/XAResource.class
javax/transaction/xa/Xid.class

Next up, convincing Maven to put it into the repository in the correct place:

bash-3.00$ mvn install:install-file -Dfile=jta-1.0.1B.jar -DgroupId=javax.transaction -DartifactId=jta -Dversion=1.0.1B -Dpackaging=jar
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'install'.
[INFO] ----------------------------------------------------------------------------
[INFO] Building Maven Default Project
[INFO]    task-segment: [install:install-file] (aggregator-style)
[INFO] ----------------------------------------------------------------------------
[INFO] [install:install-file]
[INFO] Installing c:\temp\jta-1.0.1B.jar to C:\Documents and Settings\Howard\.m2\repository\javax\transaction\jta\1.0.1B\jta-1.0.1B.jar
[INFO] ----------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ----------------------------------------------------------------------------
[INFO] Total time: 1 second
[INFO] Finished at: Thu Jan 12 18:29:55 PST 2006
[INFO] Final Memory: 2M/3M
[INFO] ----------------------------------------------------------------------------
bash-3.00$

And, with that, you have the JTA jar, in place, ready to use in your projects.

Is Tapestry "The" Web Framework?

Gregg Bolinger thinks so. I'm glad he's having such a good time with Tapestry!

Wednesday, January 11, 2006

Tapestry Get-Together / Portland, OR

I'm having a little Tapestry get-together meet-and-greet next week (Jan. 18th) here in Portland. This is just a chance for me to meet people in the area, with Tapestry being a convienient conversation starter. We'll be meeting at Henry's Tavern. Discussions should include who'se using Tapestry and how, and where Tapestry is headed in the future. Drop me a line and I'll add you to the e-vite!

Tuesday, January 10, 2006

Tapestry for IDEA

Hugo Palma is now working on an IntelliJ plugin for Tapestry: Tapestry for IDEA. He appears to be factoring out the non-Eclipse specific code from Spindle, and reconnecting it inside IDEA's APIs. It's not clear how far along this process he is, but he is promising to post screenshots shortly.

2006 looks like a true banner year for Tapestry!

Monday, January 09, 2006

Comments now moderated

Well, the latest scumbags have found a way to make life suck for everyone ... in this case, blogger.com is letting spammers post ads for DVDs on my blog. In the meantime, I'm now moderating comments.

Saturday, January 07, 2006

Tapestry on Slashdot

Is it a sign of my personal immaturity that seeing a Slashdot article on Tapestry made my heart skip a beat? This is Slashdot covering the DeveloperWorks article and caught me by surprise. Let the fud/counter-fud begin!

Phew! Tapestry 4.0 is final!

Tapestry 4.0 (final) has been released. This is a great relief to me, because I really think I could explode, or at least spontaneously combust, if this didn't happen.

I'm exceptionally proud of this release; to some degree, we've rewritten Tapestry from the inside out. The new structure, based on HiveMind, makes Tapestry exceptionally extensible, and performance appears to be better than Tapestry 3.0 (so much less reflection going on). More importantly, the coding model has improved quite a bit. Component parameters now just work ... no fumbling with "direction", listener methods are really flexible and easy to use, the validation framework is much, much simpler, and the annotation support (still optional in 4.0) is very succinct and code-focused.

We're already doing some planning for Tapestry 4.1 which better not take two years ... I'm hoping more like 6 - 9 months. I have several tasks on my plate:

  • A fast, useable, productized integration test suite (that can be used to test applications)
  • Convert to a Maven 2 build
  • Rework form support to eliminate the rewind phase
  • Remove the need for pages and components to extend from Tapestry base classes

Meanwhile, time to sit back and see what people make of this new release.

Wednesday, January 04, 2006

Servlet 2.5: Where's the regexp?

Seeing the new features in Servlet API 2.5, the feature I most needed, regular expression matching, was missing. Regular expressions are in JDK 1.4 and above (Servlet 2.5 requires JDK 1.5), so its pretty amazing that a basic feature like this is missing. Certainly, there's a long history of using regexp to map paths, as built into Apache (especially mod_rewrite).

I was really hoping for this feature, to support even friendlier URLs.

Other features I'd like to see:

  • Proper notifications about session synchronization events --- I want to know when an object is being de-serialized from another server in the cluster so I can set up some necessary ThreadLocals
  • Programatic login, and the ability to provide an application-specific login page --- I want to be able to use Tapestry's superior form support to manage logins
  • Failover notification --- I think servlets should support clustering without sharing data, but providing a notification when a failover has occured. Data could be stored in the HttpSession, but would not be replicated. This would give a good middle-ground between single-server and enterprise cluster.
  • Servlet meta-data access --- servlets should be able to find out about their URL patterns and filters

I probably could go on ... I've been working around the Servlet API for quite some time.

Meanwhile, there are some improvements. The DTDs have been simplified (allowing multiple URL patterns per servlet is a step in the right direction --- how about allowing the mapping right inside the <servlet> itself?) The new annotation support looks quite nice ... in fact, putting annotations on fields instead of on methods is the (long term) way to get Tapestry away from using abstract classes, and I can almost smell the bytecode enhancement in the approach implied by the @Resource annotation.

Setting up Tapestry

I had a present this morning, as I scanned my favorite web sites ... an article on DeveloperWorks: In tune with Tapestry by Brett McLaughlin. This is a nice, fully fleshed out article about how to set up Tapestry, build it from source, and run the demos and tutorials.

There are days when I feel the weight of the Tapestry community firm and square on my shoulders, and then there are great days like this ... where the community really gives back. These are the days that remind me of what a giant killer Tapestry can be.

Saturday, December 17, 2005

Tapestry 4.0 Real Soon Now

It's been an interesting week. First off, I had to leave my brand new apartment in Portland, OR after one night to come down to San Francisco for a three-day intensive Tapestry training session. Teaching Tapestry to twenty people in three days is a bit of a challenge, but the results were very well received; I understand that all new web development at shopping.com will be done using Tapestry.

Meanwhile, in the struggle to get Tapestry 4.0 out, the first vote for a final 4.0 release failed, with a veto by Kent Tong. At issue was the gaps in the documentation, particularily the documentation related to validation. This prompted new contributer Jesse Kuhnert to fill in the gaps there, so I'm in the process of producing a new release candidate, 4.0-rc-2, which will be up on the mirrors sometime tomorrow.

This does show that the process works ... but also underscores that the way many other projects function might not be a bad idea. Apache will generally release numbered releases at intervals, and after the fact elevate a release to "final, stable" status. Had we been following that scheme, we'd be at, say, 4.0.15 around now. If we vote that as a stable release ... well, we don't have to do any extra work beyond publicising it; it will already have been available, presumably, for a week or two minimum before such a vote.

On another front, I've been using Maven 2.0, as I try to rework HiveMind to build under Maven instead of Ant. For the most part, Maven 2 feels more like a finished work than Maven 1 ever did. I haven't been wringing my hands in frustration the same way. I just now downloaded the 2.0.1 release and will see if that fixes the few issues I have been encountering ... such as reports not been run and integrated into the site output.

This does tie together ... once HiveMind and then Tapestry are building under Maven, even having regular point releases will be much less important, since it will be quite easy for the average developer to pull down the source and build. Alas, Tapestry and HiveMind currently raise the bar for that a little too high for the casual developer.

Has anyone gone through the process of converting Forrest XML documentation to Maven XML documentation? They are similar is concept but slightly different in details; I'd like to save myself the effort of writing conversion scripts and stylesheets.

Monday, December 05, 2005

Moved to Portland

Well, now we've gone and done it. My wife and I have sold our house outside Boston and relocated to Portland, Oregon. Time to start over in an entirely different part of the country, one that seems to align better with our tastes, politics, and interests. Given the people we met at OSCON 2005 (also in Portland), I know there's a good community of open-source and Java developers around here ... I can't wait to start meeting them!

Tuesday, November 29, 2005

Two New Tapestry Committers: Jesse Kuhnert and Kent Tong

The Tapestry project has just added two new committers!

  • Jesse Kuhnert - Very active with the Tacos component library, which is the hub for Ajax components for Tapestry. He's got an inside line on what it'll take to make Tapestry the best framework for Ajax development.
  • Kent Tong - Active mentor on the user and developer mailing lists, Kent has been keeping me and the other Tapestry committers honest for quite a while now ... and he's written a great book on Tapestry 4.

Great things are afoot for Tapestry ... fresh blood, a final 4.0 release very, very soon now, and an increasing number of high profile sites in the pipeline (and no, I can't say more).

Thursday, November 24, 2005

Tapestry @ JavaForge

I'm just about done setting up Tapestry @ JavaForge, an auxillariy site for Tapestry components and extensions. I've been experimenting with Maven 2, so far with some decent success. I especially like the Wiki-ish "almost plain text" format for documentation. Maven 2 still has a number of teething issues, and I haven't even touched the critical multi-project support yet, but I'm cautiously optimistic.

No downloads just yet, but the source code is easily accessible via Subversion and builds using Maven, which is close enough.

Can you tell I'd really rather not be balancing my checkbook right now? Merry Turkey-Day!

No Tapestry at ApacheCon 2005

Hope I'm not disappointing too many people, but I will not be able to do the Tapestry Tutorials at ApacheCon on Dec 10th, as previously stated. They didn't get enough tutorial sign ups by their Nov. 12th deadline (ApacheCon does terrible marketing), and since I really hadn't wanted to do a tutorial in the first place, I offered to cancel rather than try and come up with a last-minute way to boost attendance.

I was somewhat looking forward to this, since I haven't done any speaking engagements in too long. But with Tapestry 4.0 in the final stages, plus the fact that, as I type this, I'm supposed to be stuffing books into boxes for my move to Portland, Oregon next week ... well, let's just say that skipping ApacheCon goes a small way towards easing my monumental stress level.

Wednesday, November 23, 2005

Woops! Killed JavaForge.com

I think I may have killed JavaForge. No, really. It seems to have blown up and crashed hard as I was uploading the tapestry-prop site tarball into their documenent management system.

I really want to like JavaForge because it is free, and because it allows Subversion hosting ... but any instability (it's been down for about 30 minutes now) is troubling.

Tuesday, November 22, 2005

And Apache's JIRA is down again ...

... and I was going to fix all those outstanding Tapestry bugs tonight. :-) But I can't. Sigh.

Monday, November 21, 2005

Documentation for Script Templates

We're in the final stages of Tapestry 4.0, trying to fix the most glaring documentation ommissions, and tidy up the bug list.

I've finally written documentation for the script template specification DTD, which is a very important file with the growing emphasis on JavaScript with web applications.

Tapestry has had, for a few years, some very advanced code for generating dynamic JavaScript to complement the dynamic HTML. It's centered in these script templates that take care of organizing the JavaScript into two large blocks (one at the top of the page, the other at the bottom) ... which is better than having it scattered about. As importantly, the JavaScript generation understands the need for uniqueness, to prevent name collisions in client-side variables and functions. This is the infrastructure that lets clever folks, like the ones at Tacos, create Ajaxian components that just work without any special attention by the developer ... regardless of whether there's just one such component, or dozens, on a page. Tapestry has the infrastructure to support this, with out requiring any special configuration of servlets or anything else.

Friday, November 11, 2005

Improving Tapestry performance

I just spent the week with a high profile client that is interested in potentially using Tapestry for a very large scale site ... millions of hits per hour. Their in-house framework is quite capable of operating at this scale, through a combination of draconian restrictions on database access and server-side state, and a total avoidance of any kind of reflective object access. These are people who literally cannot give an inch on performance.

One of the ideas that bounced around was something promised for some future release of OGNL: bytecode enhancement. That is, in some cases, OGNL 3 is expected to identify places where it can create a class on the fly to expedite access to a property, rather than always relying on reflective access as it does today.

Alas, that hasn't happened yet, and Tapestry is still using OGNL 2.6.7.

But, I thought, what if we created a new binding prefix to use instead of OGNL, for this purpose. Because of HiveMind, this approach can be packaged seperately from the framework proper, and plug right in.

... and it works. I built a little peformance test harness and tried to figure out how many nanoseconds it takes to perform an operation; an operation involves a read and then an update. Here's one of the operations from the harness:

        Op op = new Op()
        {
            public void run(PropertyAccessor accessor)
            {
                Long value = (Long) accessor.readProperty();

                long primitive = value.longValue();

                accessor.writeProperty(new Long(primitive + 1));
            }
        };

The PropertyAccessor object is either created from bytecode, or implemented using OGNL (so that we can make the comparisons).

I did a number of test runs, with a number of operations:

              10000 iterations |  Direct ns |    OGNL ns
------------------------------ | ---------- | ----------
                 name - warmup |    4288.00 |  847364.00
                          name |    1777.00 |   18426.00
                  int - warmup |    2891.00 |   81127.00
                           int |     838.00 |    7497.00
                 long - warmup |    2969.00 |   28207.00
                          long |     617.00 |    7256.00

             100000 iterations |  Direct ns |    OGNL ns
------------------------------ | ---------- | ----------
                 name - warmup |    4282.00 |  819634.00
                          name |     972.00 |    7527.00
                  int - warmup |    2947.00 |   74425.00
                           int |     242.00 |    5955.00
                 long - warmup |    2910.00 |   27492.00
                          long |     209.00 |    6046.00

             500000 iterations |  Direct ns |    OGNL ns
------------------------------ | ---------- | ----------
                 name - warmup |    4182.00 |  852125.00
                          name |     857.00 |    6756.00
                  int - warmup |    2958.00 |   81820.00
                           int |     170.00 |    5724.00
                 long - warmup |    2793.00 |   34990.00
                          long |     215.00 |    5785.00

          2,000,000 iterations |  Direct ns |    OGNL ns
------------------------------ | ---------- | ----------
                 name - warmup |    4251.00 |  843185.00
                          name |     823.00 |    6553.00
                  int - warmup |    2927.00 |   48788.00
                           int |     144.00 |    5799.00
                 long - warmup |    2961.00 |   34945.00
                          long |     180.00 |    6173.00

The results show that the direct access is around 10x faster than reflective access, which is in line with the general documentation about reflection in JDK 1.5. Still, I'm troubled that the cost per operation seems to continue going down as the number of operations increases. This could be the effect of hotspot (though the elapsed time seems short for hotspot to get very involved) ... or it could represent a problem in my performance test fixture.

To use this, you just use the prefix "prop:" instead of "ognl:". And, of course, it only works for simple properties, not property paths or the full kind of expressions used in OGNL.

I'm hosting the code on JavaForge and will make some kind of release available soon. Perhaps it will migrate into the framework proper at some point.

Friday, November 04, 2005

Further Down The Trail

Chris Nelson has published his second article on Trails: Further Down the Trail.

Seems like a lot of people are getting excited about Trails, and rightly so. I can see a large number of projects getting built this way. It's a great idea, it's developer-focused, it gets you great results fast. I've also seen Chris mention integrating Ajax components from Tacos. What's easier than using Tacos components for Ajax behavior ... using Trails and getting the Ajax stuff for free!

By the way, one of the most remarkable aspects of Trails is that Chris has been building Trails as a way to learn Tapestry. Either Chris is really some kind of comic-book alien machine super-intelligence (unlikely, I've met him in person), or Tapestry isn't quite as hard to learn as some people seem to think. Perhaps Chris had less Struts and JSP clutter to unlearn.