Details
-
Type:
Bug
-
Status:
Closed
-
Priority:
Major
-
Resolution: Fixed
-
Affects Version/s: Release 1.5
-
Fix Version/s: Release 1.5.1
-
Component/s: Tag Library
-
Labels:None
-
Environment:JDK 1.6.0_07, Resin 3.1.2
Description
Code in question (class InputOptionsCollectionTag, method doEndTag(), lines 345,346) :
this.value = null;
this.label = null;
Problem description:
I have the following JSP code:
<c:forEach ...>
...
<stripes:select ...>
<stripes:options-collection collection="some_collection_here" label="name" value="id" />
</stripes:select>
...
</c:forEach>
As a result of the JSP translation Resin generates the following java code:
while (_jsp_iter_269.hasNext()) {
...skip...
if (_jsp_InputOptionsCollectionTag_18 == null) { _jsp_InputOptionsCollectionTag_18 = new net.sourceforge.stripes.tag.InputOptionsCollectionTag(); _jsp_InputOptionsCollectionTag_18.setPageContext(pageContext); _jsp_InputOptionsCollectionTag_18.setParent((javax.servlet.jsp.tagext.Tag) _jsp_InputSelectTag_17); _jsp_InputOptionsCollectionTag_18.setLabel("name"); _jsp_InputOptionsCollectionTag_18.setValue("id"); }
_jsp_InputOptionsCollectionTag_18.setCollection(_caucho_expr_5.evalObject(_jsp_env));
_jsp_InputOptionsCollectionTag_18.doStartTag();
_jsp_InputOptionsCollectionTag_18.doEndTag();
...skip...
}
As you can see setLabel(), setValue() are only called once in the loop right after tag instance is lazily instantiated inside "if" statement.
Once doEndTag() method is executed during the first iteration "value" and "label" properties are nulled and then the next iteration results in incorrect HTML rendering.
Apparently Resin applies the same paradigm of tag initialization to every jsp tag, so this particular problem may potentially exist with other stripes's tags if they have similar "clean up" code at the end of the doEndTag().
It appears that Stripes 1.4.3 does not have this problem and problem only appeared in 1.5
I have not tested this particular test case with other web containers, and not sure if this sort of the "optimization" performed by Resin is appropriate, but on the other hand from the pure theoretical point of view since we do not control initialization of the tag properties shouldn't we be cleaning them ourselves?
For the sake of the others who run into the same problem here is the workaround that seems to be suppressing Resin's optimization and forces setValue() and setLabel() be called on every loop iteration:
<c:forEach...>
<c:set var="resinFixName" value="name"/>
<c:set var="resinFixId" value="id"/>
<stripes:select ...>
<stripes:options-collection collection="${some_collection_here}" label="${resinFixName}" value="${resinFixId}" />
</stripes:select>
</c:forEach>