3

I have, what I would assume, is a pretty common use case. We're rendering a simple "Comments" page using JSF on Wildfly 10.0. Each comment may have a parent comment, and child comments underneath it. Since there's no way to know ahead of time what the structure is, we'd like to create a JSF fragment and <ui:include /> it recursively to render the contents. It would look something like this...

Main page:

<ul class="comments>
  <ui:repeat value="#{myObj.comments}" var="comment">
    <ui:include src="/WEB-INF/fragments/comment.xhtml">
      <ui:param name="comment" value="#{comment}" />
    </ui:include>
  </ui:repeat>
</ul>

Comment Fragment:

<li><h:outputText value="#{comment.text}">
  <ui:fragment rendered="#{not empty comment.childComments}">
    <ul class="comments">  
      <ui:repeat value="#{comment.childComments}" var="comment">
        <ui:include src="/WEB-INF/fragments/comment.xhtml">
          <ui:param name="comment" value="#{comment}" />
        </ui:include>
      </ui:repeat>
    </ul>
  </ui:fragment>
</li>

However, when I run this code, the recursion seems to cause java.lang.StackOverflowError, regardless of how many items there are. Additionally, we see a javax.servlet.ServletException saying, "Could not Resolve Variable [Overflow]"

Is there a reason why this recursive call results in this Exception? Is there a better way to accomplish this? I've tried using <c:forEach /> to iterate over the comments, however when I do this it does not appear to work in JSF. I've tried both the http://xmlns.jcp.org/jsp/jstl/core and http://java.sun.com/jsp/jstl/core namespaces for the taglib, but the <c:forEach /> tag doesn't seem to iterate over my objects. (That is, nothing is being rendered to the page)

Any help you can give would be GREATLY appreciated.

Mr Lister
  • 45,515
  • 15
  • 108
  • 150
Shadowman
  • 11,150
  • 19
  • 100
  • 198
  • 2
    It appears from what you've posted that `/WEB-INF/fragments/comment.xhtml` contains a `ui:include` that includes _itself_. This would cause infinite recursion and eventually consume all of memory. – Jim Garrison Feb 12 '16 at 21:09
  • No, you'll notice that the comment fragment has a call in it that only recursively adds itself if the comment has child comments. I'm assuming that as long as it doesn't infinitely include itself that this should be fine. – Shadowman Feb 12 '16 at 21:11
  • 2
    I blogged about a similar construct with composites few days ago: http://balusc.omnifaces.org/2016/02/recursive-tree-of-composite-components.html It should provide insight. – BalusC Feb 12 '16 at 21:13
  • Use a different name for the inner `var` item. – user207421 Feb 12 '16 at 23:42
  • 1
    @EJP: No, that won't work as problem already occurs during view build time. Basically, an infinite component tree is being built as the `` only considers its condition during view render time. Shadowman, JSTL is part of the solution. How exactly does it fail for you? Where does `#{myObj}` come from? It would fail if it in turn also comes from `var` of `` or ``. – BalusC Feb 13 '16 at 07:53
  • 1
    This duplicates your functional requirement: http://stackoverflow.com/questions/10918137/component-to-iterate-and-render-a-nested-tree-like-object-structure-in-jsf This answers your technical problem with current attempt: http://stackoverflow.com/questions/3342984/jstl-in-jsf2-facelets-makes-sense – BalusC Feb 13 '16 at 08:16

0 Answers0