I am using tomcat 5.0.25 and it seems that forEach tag is implemented to generate an if-else chain when it is given an "items" parameter. The chain looks like this: if (_jspx_temp16 instanceof Object[]) _jspx_temp17=toIterator((Object[])_jspx_temp16); else if (_jspx_temp16 instanceof boolean[]) ... else if (_jspx_temp16 instanceof Enumeration) _jspx_temp17=toIterator((Enumeration)_jspx_temp16); else if (_jspx_temp16 instanceof Map) _jspx_temp17=((Map)_jspx_temp16).entrySet().iterator();
while (_jspx_temp17.hasNext()){...}
This lacks the final catch-all "else" clause. Because of this, if the items has a class object that cannot be handled by the forEach implementation, the temporary variable (_jspx_temp17 in this case) remains null and attempting to invoke hasNext() on it in the following while condition causes a generic NPE.
For example, the following tag expression causes this situation: <c:forEach var='x' items='${servletContext}'> <li>${x}</li> </c:forEach>
When this happens, it is very hard to debug for non-Java programmers which EL and JSTL is trying to address, HTML authors without Java knowledge. One has to read the translated Java file and understand the relationship between the .jsp and .java file.
Perhaps the better way to handle this case is to have the final "else" clause in which a JspTagException is thrown? else throw new JspTagException( "The \"items\" attribute is given an object that cannot be iterated.");
I supposed this can be done relatively easily by inserting another call to ctxt.generateJavaSource("else throw...."); in jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/tagplugins/jstl/ForEach.java
More ideally, the exception message should include the offending .jsp file name and the line number information so that the JSP authoer can easily identify the offending line, but I am not sure if it can be done easily under the current implementation framework.
Regards, -- KUROSAKA ("Kuro") Teruhiko San Francisco, California, USA http://www.sonic.net/~kuro/
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]