Pages

Wednesday, April 16, 2008

Book Review: Tapestry 5 Building Web Applications

I received an offer to review the Tapestry 5 by Alexander Kolesnikov from Packt Publishing. I use JSF for most of my web based work and I knew nothing about Tapestry save the name. At first, I thought that I would decline the offer, but decided to check it out to broaden my knowledge. I am glad I decided to look into it.

Apache Tapestry 5 is still in beta on the Apache Foundation website. I found it interesting that Alexander decided to write about a work in progress. It turns out that Alexander is heavily invested in the Tapestry project and has written a fair amount of the Tapestry 4 tutorials. If there is anyone who knows the project, it is Alexander.

The book is generally well written. It has definitely given me the knowledge I need to do Tapestry development based on it.

My harshest critique of the book has to do with the examples. Most of them work, but the project is still a moving target and some of the examples will not work with the latest code drops. The code seems to be based on version 5.0.6, The latest version is 5.0.11. If you use the maven quickstart project, it will currently use 5.0.10 as of my blog post. This constantly moving target makes writing a book difficult, but makes it even harder on the person trying to learn how to use it.

I would recommend the book to those who want a jumpstart on Tapestry 5 development. Based on the amount of changes in the project until a final release, the book will be further adversely affected. I would give it (3/5 stars).

I have a number of items which I have submitted to the publisher for errata. I will include them in my blog because the publisher is slow to post the errata.

I will cover the book in detail by Chapter.

Chapter 1
Introduction to Tapestry

This chapter covers the history of Tapestry, and provides some details of why it is special. There is nothing really technical about the chapter.

It does mention one item of interest. Tapestry 5 is a complete code re-write. They decided that instead of building on top of an existing framework with its flaws, that it would be better to re-write it from the lessons learned.

You could skip this one.

Chapter 2
Creating Your Work Environment

This chapter provides the basis for the following chapters. It explains how to install the JDK, Apache Maven, and create a "quickstart" Tapestry project. It also explains how to configure Netbeans and Eclipse for Tapestry projects.

Note: There is a note on page 21 which mentions that you should use Maven 2.0.5. The latest version as of this writing is 2.0.9. It worked fine for the projects.

The project that is created has a more current copy of the Tapestry libraries than the book was created with. The latest version is 5.0.11. My review is based on 5.0.10.

Note: On page 32 there is an inaccurate note about Netbeans not detecting changes in the template files, but requiring you to touch the Java files for the IDE to detect changes. This is not true as in Netbeans version 6.0.1.

Chapter 3
The Foundations of Tapestry

This is the first chapter in which you really start learning about Tapestry. Chapter 2 prepares your workspace for this chapter. This chapter works off of the project created in Chapter 2. It explains the basics (foundations) of Tapestry. The page template and page bean style may seem familiar to those of you who do visual JSF development in Netbeans, or Sun Java Studio Creator 2.

Tapestry components can be defined in three distinct ways and the book gives adequate examples of all three.
  1. The components can be defined in an XML template.
  2. The components can be embedded in HTML components
  3. The components can be implemented as HTML components on the page and have all Java code annotated in the page backing bean.
The third example is the cleanest separation of code as the author notes, but is not the easiest to use. The author and I both prefer the second version.

One of the coolest things I like about Tapestry is the exception handling. Let's face it, we will have bugs. The best frameworks provide the developer (and end user) with a meaningful exception page which helps to track down the errors. Tapestry has the best exception handling I have seen. It is intuitive and sensible in its approach. The best exception handling also helps novices to understand the error and how to fix it. Tapestry wins here too.

Chapter 4
Simple Components

This chapter begins to get into the meat of the framework by discussing the most common components that a web developer is likely to use: TextField, PasswordField, Label, PageLink, ActionLink, Select, Checkbox, Submit, etc.

The author begins the chapter by starting a project called Celebrity Collector. This project serves as the basis for the examples in the remaining chapters of the book. I suggest that everyone follow along with the process in their favorite IDE instead of just parsing the chapter. You will be happy you did so.

Note: On page 89, the example shows labels with some arbitrary text. The example continues on page 90-91 to explain that the text will be replaced with a sensible label based on the component ID. This will not work. The behavior has been changed in Tapestry since the author wrote the book. The default is to give priority to text between the label tags. This will override the default which is to label the component as the author mentions by component ID, or by an explicit label tag in the component.

Note: On page 117, the example for the @OnEvent tag for the submitButton will not work. The @OnEvent tag default value is "action" The submit component generates a "selected" event. In order to make the annotation work. It needs to be edited as follows:
@OnEvent(component="submitButton", action="selected")
This applies to the examples on pages 118-120 as well.

Note: On page 120, You may use the "selected" action, or rename the method to:
void onSelectedFromResetButton() {...}
This will accomplish the same objective to handle the event.

My overall impression of the chapter was that was well written and provides the basics for development with Tapestry.

Chapter 5
Advanced Components

Let me start by saying that the Grid component in Tapestry is awesome! This chapter covers advanced components like Grid, BeanEditForm, and FCKEditor. This chapter was hit hard by changes in the framework, but I have some solutions to help you along.

Remember my solutions may not work in later versions of Tapestry. I suffer from the same issue as the author that the framework is a moving target.


Note: On page 131, the author wants to demonstrate how to move the "pager" to the bottom of the page. The default on 5.0.10 is now the bottom of the page, and not the top of the page.

Note: On page 132, the example uses remove="id" , I attempted the project on 5.0.11 and noted that the parameter changed name to exclude. The functionality is the same.

Note: On page 136, the prepare() method has changed in 5.0.11. The interface was changed in 5.0.11. This example will not work in 5.0.11 as written.

Note: On page 137, you must remove the t:model="model" syntax for the page to work.

The BeanEditForm is another really cool advanced component. It makes the process of editing data a piece of cake. It is also extremely easy to implement.

The last component that the author covers is the FCKEditor. This is a component developed externally from the Apache Tapestry project. The author's intent is to show you how to implement 3rd party components.

Unfortunately, the project on Google Code has halted. The good news is it is part of a more extensive set of components also on Google. The old project is located here with links to the new project: tapestry5-components. This project has a more extensive set of components.

Note: On page 151, if you are using the new tapestry5-components library, the tag is as listed below:
<t:t5components.editor t:id="biography" t:value="celebrity"/>
Note: On page 152, the t5components parameter t:toolbarSet has two values "default" and "basic". There is no option called "Simple".

Chapter 6
User Input Validation

This chapter covers user input validation. There have been a number of changes in the framework which have changed some of the behaviors expected. The results are the same, and I think better. The changes have made it easier to perform validation for the most part.

Note: On page 167, the @OnEvent method needs to be modified as noted previously. It needs to have the value="selected" added to it.

Also, the onSubmit() method needs to return an Object not String.

Note: On page 169, the onSuccess() method needs to return Object not String.

Note: On page 170, there are a couple of items needed to make this example work. The first is that the isPasswordNotSubmitted() method. It needs to be changed as follows:

public boolean isPasswordNotSubmitted() {
return password == null;
}
The second item is that we need to check to make sure that password and password2 are not null. Since the example is to show the onValidate() method, we will check them here. Here is my modified code example:

void onValidate() {
System.out.println("In onValidate()");
if (password != null && password2 != null) {
if (!password.equals(password2)) {
password = null;
registrationForm.recordError(
passwordField,
messages.get("passwords-dont-match"));
}
}
}
This will check to make sure that both fields are not null before comparing passwords. The null check is required because onValidate() is called on each component on the page. The result would be to do a comparison of nulls, or a value to null. If you don't believe it, watch the output on the screen.

Note: On page 172, I could not get this example to work at all. I had to stick with the original code to get it to work.

Chapter 7
Internationalization and Localization

I currently work for an international company, as a result, i18n and i10n are very important. If you are working in an international market: Internet. You should care. If your audience (customers) can't read the page, they will go someplace else.

This chapter shows how easy it is to implement internationalization and localization in your work. I was amazed at how easy it is to implement. If you need translations, I recommend Google Translate.

Note: On page 177, the code example is already applied to the "quickstart" project. However, it has been changed as follows:
configuration.add(
TapestryConstants.SUPPORTED_LOCALES_SYMBOL
,
"en,de");
You will just need to add "de" for Germany (Deutschland).

Note: On page 186, the author refers to an "assets" directory. We have not created one, the sytles.css sheet is actually in a directory called "styles".

Chapter 8
Creating Custom Components

The book concludes on how to make custom components. This chapter was fun to do. It takes a lot of the work you have already done, and made it re-usable. It is quick and simple to do. If you have ever tried to make a custom JSF component, you know how difficult it can be. This is particularly true the more complex the component. Tapestry makes it so easy that I wish that this simplicity could be brought to fruition in JSF.

Note: On page 197, the author refers to the "assets" directory. It should be "styles".

Note: On page 228, the example here is the similar to page 172. I could get neither this example nor the example on page 172 to work. I recommend staying with the existing code.

Appendix A
The Basics of Java for the Web

This chapter is an introduction to web development. It is for the novice who is just trying to understand what web development is about. Very basic information.

Appendix B
Creating a Real Data Source with db4o

I did not examine this chapter since I have no interest in the subject except mere curiosity. I did read it, but did not try it. I leave this to those who wish to comment on it.


Again, I would recommend the book to those who want a jumpstart on Tapestry 5 development. I would give it (3/5 stars).

2 comments:

  1. For example of the 172 page work, use void onValidateForm() instead void onValidate().

    ReplyDelete
  2. Thanks Jorge for the additional follow-up. I had not attempted to use that functionality. I am glad to see others looking very intently at the code and examples.

    The API has changed considerably from when the book was written. The book was based on 5.0.6. The latest version (as of this writing) is 5.0.13 which is dramatically changed from 5.0.6.

    I checked the author's code on Packt and found it matches the book. I am not sure how he got it to work as published, but he is an expert. I merely was trying to follow his form using the OnValidate() method.

    ReplyDelete