Archive for August, 2007

Some wicket impressions

I already mentioned Apache Wicket in my first post and immediately received advice to not gloss “over a great framework too quickly”. This advice came from a guy named jonathan … coincidentally one of Wicket’s most ambitioned developers is Jonathan Locke, who’s always present in discussions about Wicket … so there may be a connection to that guy who left a comment to my first post :-) .

So I gave it a try. As the Wicket website suggests to use version 1.3.0beta, the first I did was to download it as maven dependency.


<groupId>org.apache.wicket</groupId>
<artifactId>wicket</artifactId>
<version>${wicket.version}</version>
</dependency>

<dependency>
<groupId>org.apache.wicket</groupId>
<artifactId>wicket-extensions</artifactId>
<version>${wicket.version}</version>
</dependency>

Then I took a look around to find some code snippets or examples that could give me a smooth start. The guestbook example on the website was the first a had a look at (well after the hello world, which doesn’t count :-) ). The guestbook was easy to understand and ran without problems …
Wicket’s AJAX support was the next thing I had a look at. I found some nice examples in the Wicket Library and on wicketstuff.org (in fact the same on both websites). And yes, it was the guestbook with added ajax behaviour which I tried first. I adapted it a bit to my needs and tried to run it. It ended up by throwing a MarkupNotFoundException which suggested to

Enable debug messages for org.apache.wicket.util.resource to get a list of all filenames tried

as Guestbook.html could not be found. I enabled debug messages by adding the following line to my log4j.properties file.

log4j.category.org.apache.wicket.util.resource=debug

The debug message I got was

[DEBUG] ResourceStreamLocator Attempting to locate resource 'org/example/wicket/Guestbook.html' on path [folders = [], webapppaths: []]

I thought “uh, there aren’t any webapppaths or folders in wicket’s path, gotta add some”. I then entered the path in the web.xml file as property of the Wicket filter. Well, the path was then inside the brackets, but the exception still got thrown.
Eventually I saw the (my) mistake: there was a <wicket:extend> tag in the markup html, which was completely new to me. Having read the wiki article about markup inheritance and having removed the tag, the Guestbook ran without problems. Yepp it was my mistake to copy-paste the thing and to overlook the tag, but couldn’t the error message be a bit better/concise?

Alastair Maw’s BeanEditPanel reminded me a lot of Tapestry’s BeanEditForm, but of course doesn’t have all the BeanEditForm’s functionality (yet). But it was a great starting point for me to get a bit more into wicket … I already extended the BeanEditPanel a bit … yes, to be honest, the more I work with Wicket, the more I like it. The use of plain html and wicket IDs is a great concept and I also like the ease of adding AJAX behaviour. Just have a look at the ajax examples.

A nice summary of wicket’s features can be found in Peter Thomas’s Blog. I also recommend to read Karthik Gurumurthy’s introduction.

The only complaints I have so far are that I could not find the source code, which would be quite comfortable to have attached to the jar, as I sometimes like to see what’s going on behind the curtain… and no I don’t want to check it out from the SVN :-) .
There’s also no link to the 1.3.0beta javadocs on the official website. I found the link in a newsgroup post.

What I’m going to find out next is how the Validators work in Wicket. In a example I found, a Validator was added to a text field for instance like that

TextField name = new TextField("name");
number.add(StringValidator.minimumLength(5));

But contrary to the javadocs, a method FormComponent.add(IValidator) is not available … which I found a bit strange …

That’s all for now, and comments, especially to the validator stuff, are always welcome ;-)


Creating custom components with Tapestry 5

As far as I’m concerned, I consider creating custom, reusable components as the supreme discipline of every web-framework. I remember fiddling about a custom tabbed panel in JSF some years ago … those were the days when it wasn’t easy to find JSF third-party components. I also remember that it took me ages to add some sort of AJAX behaviour, and I can’t really remember if I finally succeeded :-) But times have changed, creating custom components is part of every almost every framework’s ref-docs and it is … or should be … easy to create them. Ideally just with combining already existing components to new ones.

As already mentioned in my previous post, I’m playing around with Tapestry 5 these days. So I decided to create my own component, a guestbook component. The guestbook should be as generic as possible, meaning that all kinds of Java beans should be valid entries. I.e. you should not be dependent on some fixed values such as name, e-mail and the message … well that really called for a BeanEditForm to enter the values … and I thought about using some kind of Grid to display the guestbook entries.

As a complete newbie in creating tapestry components, the first way to go was the Tapestry wiki’s howto page for T5. There, Eric Vullings’s short introduction about creating custom components merely gave me a quick overview over the rendering phases to override/implement when creating a component.
Then I took a cursory glance at the BeanEditForm’s and Grid’s source code to see how the components work and how they could be extended/used for my custom guestbook component. I quickly realised that it takes a bit more than a cursory glance to get the hang of the Grid (including the GridRows, GridColumns and GridPager components) but it needs less effort to figure out how the BeanEditForm works.

I decided to take the BeanEditForm straight away as part of my component and to adapt some of the Grid’s functionality to display the entries. I soon found myself copying most of the Grid’s code …. that was the right time to stop and to think about my approach once again. I was already down in adding my own coercer to the AppModule which was a lot of fun but nevertheless copying code can’t be the solution :-) .
So I (ab)used the Grid for my custom needs. To keep it short (sorry for those of you who didn’t get in touch with the Grid so far :-) ), I let my Guestbook implement the GridModelProvider interface, subclassed GridRows in order to be able to use the a different template-html without losing the GridRows’s functionality and did the same with the GridPager component.
There it was, the Guestbook – a BeanEditForm above with GridRows and a GridPager below. All it needed now was to override the onSubmit method (or to use the @OnEvent(value = “submit”) annotation) to do with the new entry whatever I wanted.

But after all, it just didn’t feel right to abuse the Grid and to call that my “custom component”. I think I’ll never use it in a real-life application, but I got a good insight into how components work in Tapestry5 by playing with those two. Here my two pennies worth on the whole stuff:

The ‘mighty’ components in Tapestry5 seem to be hard to extend – maybe it is better to use them as they are, without trying to combine them to form a new component (which might be what the developers wanted). I believe that it wouldn’t be too difficult to create mighty components on your own, if you already created some small components. There were two little things I noticed during dealing with the GridPager component:

  • The GridPager component shouldn’t be limited to the Grid. In its current state it requires a GridDataSource object, which actually is the only link to the Grid. Basically it’s just a matter of a different naming. Thus creating a super-interface of GridDataSource (e.g. DataSource with the method getNrOfItems():int) would make the GridPager reusable for other components without having the Grid-stuff in it.
  • The CSS-class shouldn’t be hard-coded. Overriding the css would be a possibility, but it would look much neater to pass it as a parameter.

Well, that’s all for today. I’d love to hear about your experience with creating your custom components. So if you have something to say, or questions, just leave a comment below!

Unfortunately I did not find the time to look a bit more into Maven. Now even Tapestry creator Howard Lewis Ship swears like a trooper in his recent blog entry :-) . I’ll definitely have to take a more thorough look into Maven …


Tapestry/Spring Integration

In the last weeks I started to have a look at different web frameworks and came across Tapestry5. Having watched the screencasts on the website, I began to like it straight away. Although still in development (the release is planned in fall 2007), it offers some nice features. The most impressive one is that you do not have to restart the servlet-container to apply changes in java files. But for me personally, the features I appreciate the most are that you don’t have to bother with jsp-specific stuff (such as <% useBean="..." %> – Ugh!) and it lets you get rid of the servlet mapping stuff in the web.xml. That’s nice isn’t it? I also read some posts claiming that Apache Wicket already provides such features. I started reading the Wicket docs, but stopped when I saw that there’s a need to inherit from a Wicket base-class and to define servlet-mappings in the web.xml – as stated above, I don’t like too many manual servlet-mappings and I also prefer dealing with POJOs.

After playing around with Tapestry by implementing the screencasts and the tutorial, I tried to inject Spring2 managed-beans into a Tapestry5 app. I found a load of examples/tutorials online, but they either dealt with tapestry4 and/or spring1.2.x. There also is a tutorial on the Tapestry site from its creator Howard Lewis Ship. Unfortunately, he missed pointing out that it is vital to add another dependency, the tapestry-spring library. Worth mentioning is, that the tapestry-spring dependency differs from the tapestry-spring.jar available on the project page which I used at first. It took me quite a while to find out what’s wrong until I found a hint in the tapestry-mailing-list. A user there suggested to add the tapestry-spring dependency to your maven2 pom.xml. After including the library, a simple @Inject was enough to inject a spring-bean into the tapestry-class. The dependency should look as follows:

<dependency> <groupid>org.apache.tapestry</groupid> <artifactid>tapestry-spring</artifactid> <version>${tapestry-release-version}</version></dependency>

The hacks I did with Tapestry5 made me to get in touch with Maven2 for the first time. Together with the eclipse-plugin, it was very easy to add dependencies to the project and to build and pack the application. That’s of course only the tip of the iceberg, and I’ll definitely have to get a bit more into maven – as it really looks like it offers some nice features. And also I have to prove if Jelmer Kupurus’s statement is right or not :-)

Enough for now, I’d love to receive some comments with your experience with Tapestry5 and Spring integration!