February 15th, 2009 by Lincoln Baxter III

Un-Documented JSF: Reference

Add a comment with your experience or “gotcha!”

Java Server Faces is currently full of relatively undocumented features and behavior. As part of the JSF2 release, OcpSoft is working with a few folks at Seam/Redhat to try to address these issues and provide better documentation.

If you have used, or currently use JSF, we need your help.

What did you find that was backwards from what you expected? What did you find that you couldn’t find anything about? As we progress, we’ll compile the QA and make sure it gets preserved here, and on the official documentation site when it arrives, so that others don’t get lost on the same issues. It might even make it into the JSF2 specification if it needs to be fixed!

We’ll start it out:

“I used the JSF DateTimeConverter to format an input field into a Date, but the dates were sometimes one day behind. Why?”

You need to specify the timezone in each converter:

JSF1.x uses UTC by default. It does not use the server timezone!
<f:convertDateTime timeZone="America/New_York"  ... />
 
--or using a bean to specify the timezone based on the current user--
 
<f:convertDateTime timeZone="#{settingsBean.userTimezone}"  ... />
JSF2 will be addressing this issue at a configuration level, so adding timezones to each converter will no longer be necessary, but until then, you may want to think about writing a custom converter yourself.

If you need to use XML markup in your comment, please encode it first!

Otherwise it will disappear completely 🙁

Posted in Java, JSF

27 Comments

  1. Dan Allen says:

    I’ll start in no particular order.

    JSF does not reevaluate the attributes of a converter on postback. That means if you have a ValueExpression on your converter that resolves to a TimeZone, and the underlying TimeZone value changes on postback, the rendered page won’t reflect the change. You have to do a redirect so that the view is rebuilt.

    <f:convertDateTime timeZone=”#{userPrefs.timeZone}”/>

  2. Dan Allen says:

    The formal way to access the request context path in a view is with this value expression:

    #{facesContext.externalContext.requestContextPath}

    However, Facelets often attempts to emulate functionality in JSP. One way it does that is by making the HttpServletRequest available under the implicit variable named request. So you can get to the context path in less characters using this expression instead.

    #{request.contextPath}

  3. Dan Allen says:

    JSP makes it next to impossible to change the content type of the response. In fact, don’t even both trying because it’s a waste of your time. Just use Facelets. When you do, you can change the content type of the response using the <f:view> tag. The most common use case is to deliver an XML feed.

    <f:view contentType=”application/atom+xml”>

    </f:view>

  4. Dan Allen says:

    As elegant as it is, even Facelets has its skeletons. One of them has to do with the way it handles (or should I see eats) whitespace. When two components have only whitespace separating them, Facelets will trim that space so that the output of the two components are mashed together. You see this most often with links.

    Link 1
    Link 2

    gives you

    Link 1Link 2

    To get around the problem, you can place a value expression that resolves to a single space between them.

    Link 1
    #{‘ ‘}
    Link 2

    I am trying to push a fix for this problem through in JSF 2.

  5. Derek says:

    Dan, I’ve noticed something similar to your link issue in JSF 2.0. If I have 2 links side-by-side, and I don’t use an h:outputText for the 2nd links title it will add a space automatically.

    So if I do this:
    <h:commandLink>
    Link2
    </h:commandLink>

    instead of

    <h:commandLink>
    <h:outputText value="Link2" />
    </h:commandLink>

    I will see the hyperlink onhover for LInk2 look more like: Link1_Link2

    but without hovering on Link2 it appears as a space: Link1 Link2

    I still haven’t spent the time to investigate if it is a “feature” or a bug (JSF 2.0 or Facelets). I only noticed it in JSF 2.0. I’ll get the time to test it more sometime.

  6. Jason Porter says:

    I know Dan has posted about this in another blog entry (http://jsfcentral.com/articles/speed_up_your_jsf_app_1.html) so I’ll just give a short overview.

    JSF will often evaluate your EL expressions multiple times throughout the life cylce, so you have to be very careful about any logic that you put into your methods (action methods, getters, change listeners, etc).

    This is especially apparent when using the rendered attribute (Dan talks about using it inside of a data table with man rows where you really start issues). So don’t be too alarmed (unless your methods are logic heavy) about seeing those methods hit multiple times in a debugger (or log) when you view your pages.

    If those methods are logic heavy consider using a cache and returning early instead of running through all of the logic.

  7. Lincoln says:

    JSF doesn’t invoke validators on blank fields.

    You’ll need to set the required=”true” attribute in order to cause a required message to show up. Seems like validators should always be applied, even when blank.

  8. Dan Allen says:

    Jason, the space you have observed is caused by the presence of inline JavaScript. Before the very first UICommandLink on a page, JSF will insert JavaScript that allows all UICommandLinks to behave like buttons (i.e., submit the form). As a result, you get this space as an artifact. It’s really an implementation bug in Mojarra since no where in the spec does it say that you have to insert the JavaScript this way.

  9. Thai Dang Vu says:

    graphicImage accepts the onload attribute, but it’s not described here http://java.sun.com/javaee/javaserverfaces/1.2_MR1/docs/tlddocs/h/hraphicImage.html.

  10. Drew says:

    A simple gotchya.

    Value Change Listeners are evaluated before beat values are restored from the view. Therefore if you change bean data in a value change listener it will likely be overwritten when it is restored from view.

    For example, imagine a tree structure with each parent node and child node having a check box. The requirements are that if a child node is selected, all parent nodes must be selected. If you use a value change listener to change all your parent nodes, they will be overwritten when the values are restored from the view.

    To solve this, you need to re-queue your event so that it happens after the UPDATE_MODEL_VALUES phase.

  11. Facet is not really well documented.

    When a method of a managedBean returns a string like "new"

    There’s no need to use a faces-config navigation case to make correspoing this outcome point to a view, it directly works (at least with JSF2)

  12. Alpheratz says:

    I set out to build a JSF-based app. Bad Idea!

    In my design, each tab in the UI would represent a parameter-entry form. I anticipated that this could be templated out easily enough into small included files (one file for each parameter set).

    It didn’t work out that way…

    There is a little entry in the facelets FAQ entitled “I’m getting Duplicate ID Errors (and Bindings)“:

    This can be caused by a couple things. The first is when you use JSTL or logical predicates in your templates which add or remove components based on some volatile logic in your model. It’s not so much the case that your component tree can’t change between requests, but you do open opportunities for errors to occur. Sometimes explicitly providing id’s to your components corrects this problem such that JSF has no way of accidentally assigning a duplicate.

    The second way this can happen is when you using ‘binding’ attributes on your components. If you are binding components to anything other than request-scope, you can run into problems where components, and their assigned identifiers, get injected into another page, conflicting with their identifiers. Again, you can attempt to provide explicit id’s to your components to avoid conflict and guarantee uniqueness, but it doesn’t fix the greater issue with application/session scoped bindings:

    1) UIComponents are not Serializable– and therefore cannot be clustered

    2) UIComponents are not thread safe can cannot be used by multiple requests at once

    Binding UIComponents to backing beans is actually something worth doing to ease particular use cases. Instead of using a session/application scoped bean, use a request-scoped composite mediator that receives your session beans and the UIComponent instance to coordinate behavior. The injection of your session-scoped beans can be managed with the faces-config managed-property or with any of the 3rd party extensions such as Spring 2.0 or Seam.

    This issue shot the whole UI I was building down in flames. I was 80% of the way through and could not continue to use JSF. To this day, I have no solution, and I note that the FAQ entry remains.

  13. alberto gori says:

    Never never let your binding expression point to a session (or broader) scoped bean.
    It will cause lots of ununderstable issues.
    If you need binding, point it to request scoped objects instead.

  14. alberto gori says:

    You can’t inject a request scoped managed bean into a session scoped one. More generally, the standard JSF dependency injection will throw an exception if you try to set a shorter scoped bean into a broader one.

    P.S It seems that this very unconvenient implementation of dependecy injection won’t be fixed in JSF 2.0.

  15. David Johansson says:

    You can’t have a form inside &lt;ui:repeat&gt; or a &lt;h:dataTable&gt;, only the last form will actually work. &lt;h:commandButton&gt; and &lt;h:commandLink&gt; do call actions, but any field values are lost without word of warning.

    https://javaserverfaces.dev.java.net/issues/show_bug.cgi?id=928
    https://jira.jboss.org/jira/browse/RF-5773

  16. David Johansson says... says:

    I don’t experience the David Johansson’s issue.

  17. Lincoln says:

    In a form, If the JSF attribute “prependId” is set to “false”, the UIComponent.findComponent() cannot find any Components within the form.

    When prependId is left set (defaults to true), this works.

    UIComponent.findComponent() works on naming containers, and if prependId is set to false, that naming container information is lost.

  18. Fabien Mars says:

    All action listeners which are childen of an ActionSource (commandButton, commandLink) will be trigerred AFTER the ActionSource’s listener (since JSF1.2). I accept that fact, but I have to say 2 things:

    1) In my opinion the spec isn’t clear enough about that. The javadoc is also misleading.

    2) f:setPropertyActionListener is (logically) also bound to that behavior and I believe its benefit is much reduced because o that. Take the typical usecase of deleting a row in a table using a button, you need to be able to manipulate the row in the actionListener behind the button. Maaaany people try and discover that they can’t use setPropertyActionListener to set the row in a defined variable. It would be set too late, after the listener is called. Instead developers must use in their listener: ((UIData)actionEvent.getComponent()).getRowData() and cast the result again… “Why do easy when you can to difficult?” as some say.

  19. Anton says:

    Using Guice with JSF 1.2

    public clas JSFBean{
    @Inject
    private transient Service service;

    @PostConstruct
    void post(){

    getInjector.inject(this);
    }
    }

  20. Anton says:

    If you are looking for JSF component look on myFaces sandbox – it has such component

  21. jeff says:

    Customizing validation error messages should be clearer and better documented. Answer: Find them in javax/faces/Messages.properties in jsf-api.jar. Refer to your resources property with the following XML in your faces-config.xml:
    <application>
    <message-bundle>com.ocpsoft.foo.overriddenMessages</message-bundle>
    </application>

  22. Ingo Jobling says:

    Validation is the Achilles heal of Java Server Faces.

    Form-level validations are a catch-22. If you perform them in an action method, where it is convenient to compare values, the validation phase has already completed.

    From an action method, when validating values contained in a data table, it is virtually impossible to generate faces messages for a component (in a certain table row), and to set that component’s invalid attribute.

    On the other hand, when performing form-level validations during the validation phase, it is difficult to obtain the values of the other components on the page. Again, when dealing with a data table the problem is compounded.

    As another example, validations are not invoked if a field is empty. This makes is extremely complicated to implement common validations such as comparing two fields (e-mails, passwords).

    One last example: implementing validations for unique constraints.

    All of these difficulties are essentially undocumented, although, to be fair, “Core Java Server Faces” and “JSF Complete Reference”, do discuss them to some extent.

  23. Rafael Ponte says:

    A lot of developers think it’s impossible to use <b>h:commandLink</b> or <b>h:commandButton</b> components in <b>h:dataTable</b> when the managed bean is on request-scope.

    That’s not impossible if you ensure that EL evaluted on <b>h:dataTable</b> from the managed bean on request-scope always will return the same value.

  24. eustache says:

    Hi, I’m quite new to J2EE/JSF. I’m writing an application using JSF/MyFaces and Richfaces technologies. The application is running well. However, i’ve noticed a wierd behavior I can’t solve. In the application, when a user successfully connects, he gets access to some features of the application related to his role; read from a database.
    The problem:
    When a user X connects from a given browser, his profile gets updated/modifier if another user connect Y connects from another workstation. The session for user X is replaced by the last connected user Y, without even a re-login. Any help will much be appreciated, as I’ve failed to troubleshoot. I’m using IBM Websphere Application Server community edition (WASCE)
    Regards

  25. Lincoln says:

    It sounds like you have some bean-scoping issues.

    Beans should be request-scoped by default, and changed to session scoped only if you want to share data between requests.

    If you have an application-scoped bean, data stored in that bean will be shared between ALL users.

  26. eustache says:

    Thanks Lincoln. I’ve even kept all the beans to request scope…. Still the same

  27. After having implemented a pretty major JSF 1.x project about 6 months ago, I had a laundry list of issues that we ran into and ultimately surmounted. Some of the highlights:

    – h:commandButton does not support onclick in certain versions of JSF (1.0 at least)
    – Many issues with nested h:dataTables containing h:commandButton or h:commandLink
    – Issues binding the rendered attribute to an expression that involves request-scoped data. Important to note with binding expressions on the rendered attribute is that if a component is not rendered, it is not part of the tree at the time actions are evaluated. We ran into a number of strange cases with h:commandLink or commandButtons nested inside dynamically rendered components. If the parent component didn’t evaluate to rendered=”true” at the time the “Invoke Application” phase occurred, the action wouldn’t fire.
    – Many, many cases where native JSF logging is insufficient to describe what is actually going on when something doesn’t work as expected. This includes: commands not firing, validation not working, validation failures (with, in some cases, nothing going into FacesMessage), many many many NullPointerExceptions (or other exceptions) from the JSF code when incorrect value expressions are provided.
    – Errors in the faces-config file will not always be caught or reported in meaningful ways. We ran into many cases where missing brackets or simple typos would result in meaningless exceptions.
    – Obviously, the usual issues around use of arbitrary HTML in JSF 1.x applications.

    That said, the application was very complex, and once we worked our way around some of the weird issues of JSF, some of the component magic was actually very helpful.

    I think one of the big issues that developers have with JSF is that understanding the request and component lifecycle (and its bugs and quirks in implementation) can be very difficult to wrap your head around.

Reply to Drew




Please note: In order to submit code or special characters, wrap it in

[code lang="xml"][/code]
(for your language) - or your tags will be eaten.

Please note: Comment moderation is enabled and may delay your comment from appearing. There is no need to resubmit your comment.