Dennis has posted 2 posts at DZone. View Full User Profile

JSF Anti-Patterns and Pitfalls

12.12.2008
| 42574 views |
  • submit to reddit

Thread Safety

You never have to worry about some parts of the application. Calls to FacesContext.getCurrentInstance() return a thread local data structure. Request and unscoped managed beans are of course safe as well.

Other parts of you application are accessed by more than one thread at a time. PhaseListeners and Renderers are prime examples. Each PhaseListener is global to the application and it subscribes to at least one phase event for every request. The relationship between component instances and Renderer instances is many to one: components of the same type share the same Renderer instance for the entire application. Session and application scoped managed beans are obviously accessed by more than one thread.

Custom tag handlers do not need to be thread safe, but the container can reuse the tag instance. Always reset the field values by implementing the release method.

You may or may not need to make a custom Converter thread safe. Registering a Converter and using a converter tag will never introduce a race condition. The component will get a new Converter instance each time it is needed.

 

<converter>
<converter-id>threadUnsafeConverter</converter-id>
<converter-class>net.dbyrne.ThreadUnsafeConverter</converter-class>
</converter>

<h:inputText value="#{managedBean.value}" >
<f:converter converterId="threadUnsafeConverter" >
</h:inputText>

Using the converter attribute however could introduce a race condition because it is possible the same Converter instance will be used simultaneously by more than once request.

 <managed-bean>
<managed-bean-name>threadUnsafeConverter</managed-bean-name>
<managed-bean-class>net.dbyrne.ThreadUnsafeConverter</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>

<h:inputText value="#{managedBean.value}" converter="#{threadUnsafeConverter}" />

 

Custom Validators have the same thread safety constraints as custom Converters.


Facelets Migration Challenge: Tags with Behavior

Java developers have long been able to create their own JSP tags. JSF developers inherited this because the default view technology for JSF is JSP. JSF hooks into JSP by invoking the setProperties method when the JSP tag is first rendered. This is the tag handler's one chance to pass the tag attribute values on to the UIComponent mapped to the tag.

public class WidgetTag extends UIComponentELTag{

private String styleClass = "default_class";
private String title;

public String getComponentType() {
return "net.dbyrne.widget";
}

public String getRendererType() {
return "net.dbyrne.widget";
}

public void setStyleClass(String styleClass) {
this.styleClass = styleClass;
}

public void setTitle(String title) {
this.title = title;
}

public void release() {
super.release();
styleClass = null;
title = null;
}

protected void setProperties(UIComponent component) {

super.setProperties(component);

Widget span = (Widget) component;

span.setStyleClass(styleClass);
span.setTitle(title == null ? "no title" : title);

FacesContext ctx = FacesContext.getCurrentInstance();
Map sessionMap = ctx.getExternalContext().getSessionMap();
span.setStyle((String) sessionMap.get("style"));

}

}

 

An experienced JSF developer will notice a few things wrong with this picture. The styleClass field defaults to "default_style", the value of the title field depends on ternary logic, and one of the component values is derived from a value expression. Unfortunately all three of these behaviors have been implemented in the tag handler.

Each rendering behavior is lost when the component is used with an alternative view technology such as Facelets. When we develop custom JSF components, it is important to place this kind of logic out of a tag handler. The Apache MyFaces code base is a good example of this. The source code for 25 components and 25 tag handlers of the JSF 1.2 implementation are generated from meta-data at build time, with no behavior.

Published at DZone with permission of its author, Dennis Byrne.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Bruce Fancher replied on Mon, 2008/12/15 - 2:20am

Using JSF is itself an anti-pattern.

Manrico Corazzi replied on Tue, 2008/12/16 - 9:11am

So it turns out I'm not the only one utterly disliking JSF... :)

Marc Stock replied on Tue, 2008/12/16 - 2:06pm

+1 to Bruce Fancher

 Asking about JSF pitfalls is like sticking your hand in a fire and asking, "What are the pitfalls of sticking your hand in fire?" 

Omar Palomino S... replied on Thu, 2008/12/18 - 2:19pm in response to: Bruce Fancher

Wich alternatives do you propose that gets same tool support and ajax integration? I'm looking to speed-up time-to-develop projects and I really want to know about the alternatives to JSF-Ajax frameworks. Hope anyone could give a hand here.

Dzmitry Churbanau replied on Mon, 2008/12/22 - 11:46pm

Bruce Fancher, Manrico Corazzi and Marc Stock: everybody can criticize (read write this is bad and so on) but not everybody can give any valuable reason to it.
So, what is your reason? Can you give any reason, or it is just "i don't like it"? :)

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.