Technical Articles relating to Oracle Development Tools and Frameworks

  • ADF
    September 4, 2012

forEach and Facelets - a bugfarm just waiting for harvest

Duncan Mills

An issue that I've encountered before and saw again today seems worthy of a little write-up. It's all to do with a subtle yet highly important difference in behaviour between JSF 2 running with JSP and running on Facelets (.jsf pages). The incident I saw today can be seen as a report on the ADF EMG bugzilla (Issue 53) and in a blog posting by Ulrich Gerkmann-Bartels who reported the issue to the EMG. Ulrich's issue nicely shows how tricky this particular gochya can be. On the surface, the problem is squarely the fault of MDS but underneath MDS is, in fact, innocent.

To summarize the problem in a simpler testcase than Ulrich's example, here's a simple fragment of code:

<af:forEach var="item" items="#{itemList.items}" varStatus="vs">
<af:commandLink id="cl1" text="#{item.label}" action="#{item.doAction}" 

Looks innocent enough right? We see a bunch of links printed out, great.

The issue here though is the id attribute. Logically you can kind of see the problem. The forEach loop is creating (presumably) multiple instances of the commandLink, but only one id is specified - cl1. We know that IDs have to be unique within a JSF component tree, so that must be a bad thing?  The problem is that JSF under JSP implements some hacks when the component tree is generated to transparently fix this problem for you. Behind the scenes it ensures that each instance really does have a unique id. Really nice of it to do so, thank you very much.

However, (you could see this coming), the same is not true when running with Facelets  (this is under 11.1.2.n)  in that case, what you put for the id is what you get, and JSF does not mess around in the background for you. So you end up with a component tree that contains duplicate ids which are only created at runtime.  So subtle chaos can ensue.  The symptoms are wide and varied, from something pretty obscure such as the combination Ulrich uncovered, to something as frustrating as your ActionListener just not being triggered. And yes I've wasted hours on just such an issue. 

The Solution 

Once you're aware of this one it's really simple to fix it, there are two options:

  1. Remove the id attribute on components that will cause some kind of submission within the forEach loop altogether and let JSF do the right thing in generating them. Then you'll be assured of uniqueness.
  2. Use the var attribute of the loop to generate a unique id for each child instance.  for example in the above case: <af:commandLink id="cl1_${vs.index}" ... />.

 So one to watch out for in your upgrades to JSF 2 and one perhaps, for your coding standards today to prepare you for.

For completeness, here's the reference to the underlying JSF issue that's at the heart of this: JAVASERVERFACES-1527

Join the discussion

Comments ( 4 )
  • Dominik Thursday, September 20, 2012


    thanks for the information you shared. We ran also into the problem with the forEach and tried your proposals and both worked, GREAT!

    However I have to use the second one as I have to reference the component by id in another component of the forEach loop.

    It is the one with the id="cl1_#{vs.index}".

    With JDeveloper it works, compiling, debugging, running and building.

    I can create an ear from JDeveloper, but not with standalone ojdeploy.exe anymore.

    There is an error in the APPC section:

    Its illegal to specify deferred expression for dynamic attribute.

    Do you know any switch or hint to get around this. Because of the error the build fails, but it works when building with JDeveloper with the same workspace and project.

    Using JDeveloper



  • Duncan Thursday, September 20, 2012

    If you are using Facelets then there is no need to use APPC to pre-compile as that's designed to handle the JSP -> Servlet -> Java byte code compilation. If OJDEPLOY does fail with a simple facelets page using this syntax You should report this via support.

    Incidently this issue will be gone in 12 as we'll be picking up the newer version of JSF that fixes this issue in the core.

  • Dominik Thursday, September 20, 2012

    It is a facelet fragement jsff file and should not be pre compiled. I don't know why it is compiled, or how to turn it off, so it may be a bug in ojdeploy.

    I got a workaround to use immediate evaluation instead of deferred.

    So this is working:


    The pre compiler is not complaining about this one.

  • Duncan Friday, September 21, 2012

    Good solution!


Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.