How do I run the JSF examples with JBoss?

While JBoss uses Tomcat as its web container internally, installation of a web application and configuring simple authentication differ from how it’s done for a stand-alone Tomcat (which is what the book describes). In addition, JBoss bundles the MyFaces JSF implementation libraries, casuing a conflict with the JSF RI libraries included with the book example application. So, how do I resolve these differences so I can run the JSF book examples with JBoss.
Answer:
Pete Bennett at JBoss/Red Hat has been kind enough to provide an answer to this question, available here:
http://wiki.jboss.org/wiki/Wiki.jsp?page=OReillyJSFExamplesInJBoss

Does the JSF book cover the JSF 1.1 spec?

The JavaServer Faces specification version 1.1 was released May 28, 2004. Does this mean that the JavaServer Faces book is now obsolete, since it’s written for the 1.0 version of the specification?
Answer:
The 1.1 version of the specification is what’s formally called a “maintenance release”, but between you and me, “bug fix release” would be a more appropriate label in this case. Most of the changes are corrections of things that were clearly wrong in the 1.0 spec, such as copy/paste errors in JavaDocs method descriptions, descriptions of behavior that didn’t match the Reference Implementation (RI), and descriptions of behavior that resulted in invalid HTML (such as multiple HTML elements with the same idattribute value). The rest are clarifications of details that were underspecified in the 1.0 specification, which are important for JSF implementors but not so important for JSF application developers (the target group for the book).I discovered and reported many of these errors while writing the book, and therefore described the features as they should be rather than how the 1.0 specification incorrectly described them. The book therefore already covers most of the JSF 1.1 changes.

There are, however, a few details (primarily in the Appendices) that are affected by JSF 1.1 and a few things about the JSF 1.1 RI that you should be aware of. They are described below.

Default error messages

The JSF 1.1 RI includes the component client ID in the default error messages, so the message shown in Figure 7-1 looks slightly different. This is a change that isn’t described in the specification so other implementations may not support the message text parameter needed for this to work (which arguably means that the RI isn’t spec-compliant). Including a component identifier in the error messages is a good idea, but the client ID is a very poor identifier, because it can’t be localized and it’s typically a string that the end user doesn’t understand (such as “_id1:_id2”). A future version of the JSF specification will likely address the need for localizable, user friendly component identifiers in the standard messages in a much better way.

New <facet> faces-config.xml element

A new <facet> element can be used in a JSF 1.1 faces-config.xml file to declare facets supported by a component or a renderer, allowing a JSF development tool to list supported facets in addition to properties and attributes. To use this feature, you must use a JSF 1.1 DTD declaration in the faces-config.xmlfile instead of the JSF 1.0 DTD shown in Example E-1, like this:

<!DOCTYPE faces-config PUBLIC     
  "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.1//EN"
  "http://java.sun.com/dtd/web-facesconfig_1_1.dtd">

The new <facet> element can be used as a subelement of the <component> and <renderer> elements, just before the <attribute>subelement (see the descriptions for these elements in Appendix E), and has this syntax:

<facet>
  [<description [xml:lang="lang"]>description</description>]*
  [<display-name [xml:lang="lang"]>displayName</display-name>]* 
  [<icon [xml:lang="lang"]>
    [<small-icon>iconPath<small-icon>]
    [<large-icon>iconPath<large-icon>]
  </icon>]*
  <facet-name>facetName</facet-name>
</facet>

Refactoring of the UIInput validate() method

In order to fix a bug with value change events firing for UISelectMany and UISelectOne components when no value was submitted, the UIInput validate() method has been split into three methods. This affects the UIInput method descriptions in Appendix C like this:

New method:
protected Object getConvertedValue(javax.faces.context.FacesContext context, Object newSubmittedValue)

Returns the submitted value after possible conversion to the data type for the local value, performed by calling getConvertedValue() on the component’s Renderer (if any) or getAsObject() on the Converter returned by getConverter (if any) or the Converter returned by the Application createConverter() method for the data type of the ValueBinding (if any). If the conversion fails, calls the addMessage() method of the current FacesContext with a CONVERSION_MESSAGE_ID message.

Modified method:
public void validate(javax.faces.context.FacesContext context)

If getSubmittedValue() returns a non-null value, calls getConvertedValue() to convert the submitted value to the local value data type and calls validateValue() to validate the converted value. If the valid property is still true, calls getValue() to get the previous local value, stores the new local value by calling setValue(), resets the submitted value, and if the previous local value is different than the new local value, queues a ValueChangeEvent.

New method:
protected void validateValue(javax.faces.context.FacesContext context, Object newValue)

If the valid property is true, verifies that the local value isn’t null or an empty String if the required property is set to true, and calls addMessage() with a REQUIRED_MESSAGE_ID message and isValid() with the value false if it is. Otherwise, continues validation by calling the validate() method on each registered Validator instance, followed by a call to the validator method binding (if any), catching any ValidatorException and calling addMessage() with the message from the exception and setValid() with the value false if one is thrown.

This change also affects the method descriptions for UISelectMany and UISelectOne like this:

Removed method:
public void validate(javax.faces.context.FacesContext context)

This method is not overridden in JSF 1.1

New method:
protected void validateValue(javax.faces.context.FacesContext context, Object newValue)

Extends the inherited behavior by verifying that the selected value (or values) matches one of the available choices. If not, calls addMessage() on the current FacesContext with an INVALID_MESSAGE_ID and calls setValid() with the value false.

UIViewRoot getRenderKitId() default

This method returns null in JSF 1.1, not the ID for the default HTML renderkit as it did in 1.0 (which is what the method description in Appendix C says).

UIComponentTag setProperties() behavior

This method description has been updated to match reality in JSF 1.1, which is that it sets the rendered and rendererType properties and nothing else. The method description in Appendix D and the description in Chapter 13 (page 256) incorrectly say that it also sets the id and binding properties, but those are in fact set by the findComponent() method.

Nesting of UIData components

Some improvements have been made in JSF 1.1 to allow UIData components to be used as columns for another UIData component, but it doesn’t go far enough to solve all problems related to this. The book says in Chapter 10 (page 192) that you can nest UIData components, but this is not true for JSF 1.0 and 1.1.

UIOutput/Label limitations lifted

With JSF 1.1, the for attribute for the <h:outputLabel>action element is optional, letting you define the labeled component as a child component instead, e.g.:

<h:outputLabel value="MyLabel">
  <h:inputText value="#{myBean.myValue" />
</h:outputLabel>

The warnings about the RI behavior in Appendix A (about the ordering of the action elements and that the value attribute is ignored) no longer apply for the JSF 1.1 RI.

Rendering of selection components

JSF 1.1 corrects and simplifies the rendering of the UISelectOne/Radio and UISelectMany/Checkbox component/renderer combinations, by rendering the id, style and class attributes on the outer HTML table instead of on a wrapping <style> element, and by no longer rendering the for attribute on the <label> elements wrapping the <input> elements for the choices. This means that the descriptions of these component/renderer combinations in Appendix C and the corresponding tag library actions in Appendix A are slightly off base for JSF 1.1.

Why isn’t my EL expression evaluated?

In a JSP 2.0 container, such as Tomcat 5, my EL expressions in template text and action element attributes are not evaluated, they are used as-is instead. For instance:

   ${now.time}

is rendered as:

   ${now.time}

What have I missed?

Answer:
The EL evaluation is disabled for a web application with a Servlet 2.3/JSP 1.2 deployment descriptor (web.xml file) for backwards compatibility reasons.

You need to update the web-appelement in your web.xml file to the Servlet 2.4/JSP 2.0 format to enable EL evaluation by default:

<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee web-app_2_4.xsd"
  version="2.4">
  ...
</web-app>

As an alternative, you can enable EL evaluation of a page-by-page basis with the isELIgnored attribute of the page directive, or with a JSP configuration group in the web.xml file.

What’s new in the 3rd edition?

I already have an earlier edition of your book. What am I missing if I don’t buy the new, third edition?
Answer:
If you have the 1st edition of the book, the 3rd edition is almost like a brand new book on the subject. So much has changed between JSP 1.1 (covered by the 1st edition) and JSP 2.0 with JSTL 1.1 (covered by the 3rd edition), making it a lot easier to develop maintainable web applications in less time.Even compared to the 2nd edition, the 3rd edition is significantly different. Here’s how the changes are described in the Preface:

If you’ve read the second edition of JavaServer Pages, you’ll notice that, in this edition, even more of the custom components used in previous edition have been replaced in favor of the equivalent standard components from JSTL—–a specification I’ve been lucky enough to contribute to and help shape the standard based on many of the ideas explored in the first and second editions. You’ll also notice that all the chapters have been modified (some more than others) to cover the new features in the latest versions of the JSP and JSTL specifications. A brand new chapter has been added to describe how to develop custom tag libraries using the new tag file format, and the chapters about custom library development using Java has been substantially expanded to cover the new, simplified tag handler API as well as the new mechanism for including Expression Language functions in a tag library. All chapters have also been updated to cover the features and clarifications added in the Servlet 2.4 specification on which JSP 2.0 is based on. Here’s a brief summary of the primary changes in all the specifications covered in this book:

  • Incorporation of the Expresssion Language (EL) (first introduced by the JSTL specification) in the JSP specification (making it available to all standard and custom components as well as in template text)
  • The EL extended with a function call mechanism and a set of common functions added to JSTL.
  • Addition of the ability to develop custom tag libraries as tag files (text files with JSP elements) as well as a new, simplified tag handler Java API, and various new tag library features such as support for a dynamic attribute list and executable fragment attributes.
  • More flexible rules for JSP pages written as XML documents, and support for the the JSP directives and scripting elements XML syntax in regular JSP pages..
  • New JSP standard elements, primarily to allow for more flexible attribute value assignments and to support the new tag file format and XML format enhancements.
  • Access to more information in a JSP error page and adjustement of the attribute names to match the Servlet specification.
  • Stricter container requirements to improve syntax error reporting and debugging support for JSP pages.
  • XML Schema-based deployment descriptors for all specifications, with new configuration options, including automatic include of page segments, page encoding specification, scripting element disabling, and more for JSP.
  • Addition of a new request listener component type and filters that can be applied to internal requests
  • Deprecation of the single thread model for both servlets and JSP.
  • New JSTL tag library URIs and a few attribute name changes for the XML library.

Why doesn’t Tomcat find my tag library or JSTL?

When I’m running the JSP examples (or some other JSP page that uses a tag library), I receive this error:

org.apache.jasper.JasperException: This absolute uri (http://java.sun.com/jstl/core) cannot be resolved in either web.xml or the jar files deployed with this application

But the tag library JAR files are installed in WEB-INF/lib as the should. What’s wrong?

Answer:
In most cases, you get this error because of one of these issues:

  • There’s a syntax error in your web.xml file. Check the log files and fix any problems listed there.
  • You have mistyped the uri attribute value in the taglib directive. Note that the JSTL URIs changed between the 1.0 and 1.1 version. Make sure you use the URIs that match the version you use!
  • You don’t have all (or the correct) JAR files in the WEB-INF/lib directory, e.g., you’re missing the JSTL standard.jar file or you have the JSTL 1.1 JAR files and try to use the JSTL 1.0 URIs. Note that the examples for the 2nd edition of the book come with JSTL 1.0, and the 3rd edition examples come with JSTL 1.1.
  • You’re trying to use JSTL 1.1 in a JSP 1.2 container, such as Tomcat 4. You need a JSP 2.0 container for JSTL 1.1, e.g., Tomcat 5.
  • You have taglib elements in the web.xml file that conflict with the auto-discovered tag library URIs. Remove all taglib elements from the web.xml file; you don’t need them if you use JSP 1.2 or later.
  • You have TLD files in the WEB-INF directory that conflict with the auto-discovered tag library URIs in the JAR files. Remove all separate TLD files outside of JAR files.
  • Your WEB-INF directory name isn’t in all caps, e.g., it’s something like web-inf, Web-inf or Web-Inf instead; Java is case-sensitive, and the directory name must be in all caps.

For very old versions of Tomcat (e.g., Tomcat 4.0.4) , another reason for this can be that the CATALINA_HOME/temp directory is missing, see http://issues.apache.org/bugzilla/show_bug.cgi?id=11489 for details

Create this directory if it’s missing, restart Tomcat and try again.

What’s new in the second edition?

I already have the first edition of your book. What am I missing if I don’t buy the new, second edition?
Answer:
The second edition is a major update of pretty much all chapters and also includes some new chapters. Here’s what one reader says about the second edition on Amazon.com:

Many new editions of technical books I have purchased have not entirely been worth the purchase price. Usually the updated material is limited in scope or fairly light. The new edition of this book is definitely worth it.[…]

Overall, I consider this book, especially this edition, an absolute must have in my professional bookshelf.

And here’s an excerpt from the Preface that describes the differences compared to the first edition:

Readers of the First EditionIf you’ve read JavaServer Pages, 1st Edition, you will first of all notice that in this edition, most of the custom components have been replaced in favor of the equivalent standard components from JSTL; a specification I’ve been lucky enough to contribute to and help shape the standard based on many of the ideas explored in the first edition. Secondly, you’ll notice that all chapters have been substantially improved and extended, and that new chapters have been added to highlight important features such as custom actions and JavaBeans, explain how to process XML data, and how to integrate your custom components with the standard JSTL components.

All chapters have also been updated to cover the features and clarifications added in the JSP 1.2 and Servlet 2.3 (which JSP 1.2 is based on) specifications, primarily:

  • New XML syntax for JSP pages.
  • New listener and filter component types.
  • New tag library validator.
  • New options for tag library deployment and distribution.
  • New tag handler interfaces and return values.
  • New tag library descriptor elements to minimize the need for TagExtraInfo classes
  • Improved support for pages stored in other encodings than ISO-8859-1.
  • Improved rules and a new mechanism for attribute value conversion.
  • Improvements to the include action.
  • Clarifications of the reuse of tag handler instances and their lifecycle.
  • Alignment of the tag library descriptor elements with the elements in other J2EE descriptors.

Can I run the examples from the first edition with Tomcat 4.0?

I know that the JSP 1.2 specification is now final, and that Tomcat 4.0 implements the new specification. Is there anything special I need to do to run your JSP 1.1 example application from the first edition of the book with Tomcat 4.0?
Answer:
JSP 1.2 is backwards compatible with the JSP 1.1 specification, so any JSP 1.1 application should run unchanged with a JSP 1.2 compliant container. Besides Tomcat 4.0, other containers also implement the new Servlet 2.3 and JSP 1.2 specifications.You install Tomcat 4.0 pretty much the same way as described for Tomcat 3.2 in the book. The only difference is that you should set the CATALINA_HOME environment variable instead of the TOMCAT_HOME variable. This name change refects the fact that the servlet container part is actually called Catalina, while the JSP part is called Jasper: combined they are called Tomcat.You start and shut down Tomcat 4.0 just as Tomcat 3.2, using the startup and shutdown scripts in the bin directory.

Tomcat 4.0 uses a slightly different directory structure than Tomcat 3.2, but the web application directory is still named webapps. This means that you can install the example application exactly as described in the book: copy the ora directory from the jspbook.zip file to webapps/ora. That’s all there’s to it.

If you like to use the example custom tag library in another application, you can take advantage of the new auto-discover feature for tag libraries introduced in JSP 1.2. This way you don’t have to mess around with tag library declarations in the web.xml file. See my JSP 1.2 article for details.

That said, I recommend that you migrate to the JSP Standard Tag Library (JSTL) instead of using the custom tag library from the first edition of the book. The second edition of the book covers all you need to know to use the JSTL actions.

The toaster and the wolf: the cover story

My copy of the first edition of your book has a toaster on the cover, but your site, Amazon.com and others show a cover with a wolf. What’s going on?
Answer:
For the first edition, the first printing came out with the toaster cover. And even though it was released in December 2000, the printing history incorrectly says January 2001. I guess the publisher was not sure it would make it out in December.

O’Reilly has now decided to use animal covers for all their books, including the Java series. So the latest printing has the wolf cover instead. Similar changes will be done to all O’Reilly Java books, and some of them are already out. You can read more about this change at the O’Reilly site, and also let them know what you think about it.

The second edition of the book will have the wolf cover in all printings, unless O’Reilly change their mind again 🙂

How can I prevent IE from caching responses?

I’m using the <ora:noCache> action described in Chapter 12 in your book, but Internet Explorer caches the responses anyway.What can I do to prevent caching?
Answer:
Unfortunately, IE is infamous for ignoring cache headers and it seems like different versions of IE have different bugs in this area. Using the <ora:noCache/> custom action from Chapter 12 in the main JSP file shouldwork, but I can’t guarantee that since some browsers are buggy. One thing you can try is to use the value 0 or -1 instead of 1 for Expires. Before changing the code for <ora:noCache>, you can test with a scriptlet:

<%
  response.addHeader("Pragma", "No-cache");
  response.addHeader("Cache-Control", "no-cache");
  response.addDateHeader("Expires", -1");
%>

Another trick is to use the corresponding meta tags both at the top and at the bottomof the JSP page:

<HTML>
  <HEAD>
    <META HTTP-EQUIV="Pragma" CONTENT="no-cache">
    <META HTTP-EQUIV="Expires" CONTENT="-1">
  </HEAD>
  <BODY>
    The content ...
  </BODY>
  <HEAD>
    <META HTTP-EQUIV="Pragma" CONTENT="no-cache">
    <META HTTP-EQUIV="Expires" CONTENT="-1">
  </HEAD>
</HTML>

This is, of course, invalid HTML but it’s a solution MS provides for this bug, see http://support.microsoft.com/support/kb/articles/Q222/0/64.ASP

On the server side, to make sure that changes to the JSP file take effect immediately, you should always use the include action, i.e. <jsp:include>. This has nothing to do with browser caching, though. See the book and my Top Ten Tips article for more on the different ways to include page fragments and what happens when the included fragment is changed.

Finally, if everything else fails, you can make sure each request is done with a unique URL by adding a dummy query string parameter, e.g. a timestamp like “?ts=123456”. A browser can not use a cached result if the query string is different from the one for the cached result.

Why doesn’t an empty field reset my bean property?

As you explained in When can a parameter value be null?, an empty text form field value is typically sent to a JSP (or servlet) page as an empty string parameter value.But a String property in my bean corresponding to a text field does not get set to an empty string when I use the setProperty action. What’s going on?
Answer:
I describe this in Chapter 15 in the book, in the section Unexpected <jsp:setProperty> Behavior.To match the behavior for properties corresponding to checkboxes, radio buttons and selection lists, the JSP specification says that if a parameter value is an empty string, the corresponding property setter method should notbe called. So when you use

<jsp:setProperty name="foo" property="*" />

for a bean with properties corresponding to various types of form elements, an empty text field has the same effect as a checkbox that is not checked; the property is not set at all.

If you use a bean to capture form input and you want to reset a property when the user clears the corresponding form field, you can use this work-around. First create a method in the bean that resets all properties:

public void setReset(String ignored) {
  myFirstProperty = null;
  mySecondProperty = null;
  ...
}

Now you can invoke this method before you set the properties based on the current form field values in your JSP page:

<jsp:setProperty name="foo" property="reset" value="dummy"/>
<jsp:setProperty name="foo" property="*" />