Daniel Bleisteiner
Daniel Bleisteiner

Reputation: 3330

<c:forEach> randomly doubles first or last item – is this a known bug?

I've now spent about 3 hours debugging a strange behaviour with the following code snippet. I'm using a dynamic <rich:dataTable> with <c:forEach> to include a changing set of <rich:column> elements during runtime.

This works perfectly in 9/10 cases. But sometimes the first or last column is doubled. Have a look at the following stripped down example:

<f:subview id="sv-#{delegate.uuid}">

    <rich:dataTable value="#{TabellenDelegateHelper.findRowsTabelle(delegate)}" var="row" rows="#{TabellenDelegateHelper.map(delegate).rows}">
        <rich:column>
            <f:facet name="header">
                <h:outputText value="Fixed Column" />
            </f:facet>
        </rich:column>

        <c:forEach var="theColumn" items="#{TabellenDelegateHelper.findColumns(delegate)}" varStatus="loop">
            <rich:column>
                <f:facet name="header">
                    <h:outputText value="#{theColumn}" />
                </f:facet>
                <!-- stripped dynamic content -->
            </rich:column>
        </c:forEach>
    </rich:dataTable>

</f:subview>

That code is included in several views using the following snippet:

<ui:include src="/WEB-INF/templates/shared/tabelle.xhtml">
    <ui:param name="delegate" value="#{myTable}" />
</ui:include>

While debugging and even using simple System.out.println(...) statements the collection returned by TabellenDelegateHelper.findColumns(delegate) always contains the expected (not doubled) elements.

To further investigate I've added some more tags after the table:

<c:forEach var="theColumn" items="#{TabellenDelegateHelper.findColumns(delegate)}" varStatus="loop">
    <h:outputText value="#{theColumn}, " />
</c:forEach>
<br/>
<ui:repeat var="theColumn" value="#{TabellenDelegateHelper.findColumns(delegate)}" varStatus="loop">
    <h:outputText value="#{theColumn}; " />
</ui:repeat>

Those two loops generate different results:

Example Image

Has anybody experienced this before? I won't believe that JSTL Core is buggy... but so far I've no other clue.

Even more strange... if I reverse the order and append <ui:repeat> before <c:forEach> the collection is correct even if the table above shows the bug. Using <c:forEach> before <ui:repeat> before <c:forEach> the 1st is broken and the 2nd + 3rd output are correct.

To make it a little more detailed... the following COLUMNS are the ones returned by the method:

private static final String COL_FIRSTNAME  = "firstname";
private static final String COL_LASTNAME   = "lastname";
private static final String COL_TEAM       = "team";
private static final String COL_POSITION   = "position";
private static final String COL_ASSIGNMENT = "Aktion";

private static final List<String> COLUMNS = Arrays.asList(COL_FIRSTNAME, COL_LASTNAME, COL_TEAM, COL_POSITION, COL_ASSIGNMENT);

Upvotes: 2

Views: 242

Answers (0)

Related Questions