Tuesday, July 26, 2005

Tapestry 4.0-beta-3, TapestrySupport.com

Tapestry 4.0-beta-3 is now available; it's more bug fixes. I've reworked how automatic cursor positioning works; it's no prioritized: first field in error, or first required field, or just plain first field. You can now turn off automatic cursor positioning (aka "focus") but settting the enclosing Form's focus parameter to false.

I've also started reviving the Virtual Library example. I'm having a little trouble getting McKoi DB deployed into JBoss 4. I briefly considered switching over to Derby, but that's not available via the Maven repository yet (still alpha).

The Virtual Library will change quite a bit as I get it working for Tapestry 4.0, as I rework it to use all the nifty features (including annotations). I'm keeping notes to form a more general Tapestry 3.0 -> Tapestry 4.0 upgrade guide.

Meanwhile, after much too long, the TapestrySupport.com web site has gone live, and a press release is going out. This is a site dedicate to professional support of Tapestry. Check it out!

Friday, July 22, 2005

Don't shit where you eat

I made a recent change to the set of build scripts used by Tapestry and by HiveMind; it no longer builds inside my workspace. Let me explain why this is a good thing.

Your workspace is supposed to be a local image of the files stored in your source code repository, so that you can make changes to those files, then follow a compile/test/fix cycle, and eventually check the source files back in.

A common problem in many projects is when derived files, .class files, or .jar files, get accidentally checked in to a project repository. This can cause a lot of confusion, and may be difficult to clean up.

But more importantly, I've noticed when using Eclipse is that the number of files (not source files, but file system files) in my workspace affects the performance of the IDE. Somewhere, in the background, it is constanty checking for changes and re-indexing files using Lucene. Builds of Tapestry and HiveMind create a huge amount of documentation ... Javadoc, HiveDoc, test reports, clover code coverage and so forth. Thousands upon thousands of files ... none of which are interesting to me as a developer.

In the old scheme, all the output classes and jars and instrumented Clover source files, and everything else, were in target directories inside the workspace.

That's whay I mean about shitting and eating; it's better to stay clean.

What I did was change my Ant build files to create the target directories under ${java.io.tmpdir}. That is, a shadow project structure is created there, directories like C:\WINDOWS\TEMP\jakarta-tapestry\workbench\target. Just about everything goes there, except for a handful of output jar files (as a convienience) and some Forrest files (out of necessity).

My builds and my IDE run better and faster now. I think this is a model that should be followed by other build tools, such as Maven.

Sunday, July 10, 2005

Tapestry 4.0-beta-2

The newest release of Tapestry is available for download. The changes are largely bug fixes, mostly for problems with annotations and client-side JavaScript.

There's also the start of a Quick Start tutorial.

Tapestry JavaOne Examples Available

I've finally had a chance to package and upload my source code and presentation from JavaOne 2005. It's available as http://howardlewisship.com/downloads/javaone-examples.tar.gz

Thursday, July 07, 2005

<> vs. () makes me :-(

All I wanted was fewer casts. I'm sick of typing all those casts (they tend to get out of control when using EasyMock). The compiler knows enough about the left and right side of my assignments to require a cast, why can't it just provide it (this is the Dave Thomas observation).

Now, in an attempt to simplify things, we've replaced casts with generic type constraints. So instead of:

Map _map = new HashMap();

public RegistrationData getRegistration(String userId)
{
  return (RegistrationData) _map.get(userId);
}
With generics we get:
Map<String, RegistrationData> _map = new HashMap<String, RegistrationData>();

public RegistrationData getRegistration(String userId)
{
  return _map.get(userId);
}
So, much more repetition and uglier code to avoid that one little cast. A cast the compiler could just as easily have provided for me? One that still exists at runtime (that's type erasure). This is simpler?