Skip to main content

Crazy JSTL: when an empty Collection is not empty

Posted by mister__m on November 27, 2003 at 8:32 PM PST

Previously, I have promoted JSTL as an easier way to code the web tier. While I haven't changed my mind about it, I have just come accross one of its pitfalls yesterday, a few minutes after writing a blog entry about grid computing. Have you ever been in a situation code that looked impossible to be incorrect actually was incorrect? Well, it happens in many occasions, generally in the most unwanted ones - as it did yesterday, when it was around 3 am in Brazil.

Let's go straight to the point: for those of you who are familiar to JSTL, consider the following code:

<%-- Block 1 --%>
<%@ page import="java.util.Collection" %>
<%
    Object o = request.getAttribute("collection");
%>
<%= (o instanceof Collection) && ((Collection)o).isEmpty() %>

<%-- Block 2 --%>
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>

Assuming the first block prints true and that the Collection implementation used is flawless, what does the second block prints? true, right? Wrong! The right answer is: it depends.

Wait a minute: it depends? But how? Verbatim from the JSTL spec 1.0, section 3.8:

To evaluate empty A:
    If A is null, return true,
    Otherwise, if A is the empty string, then return true.
    Otherwise, if A is an empty array, then return true.
    Otherwise, if A is an empty Map, return true
    Otherwise, if A is an empty List, return true,
    Otherwise return false.

So, the JSTL 1.0 spec says nothing specifically about using the empty operator to evaluate Collections; it just supports the intended behaviour - the one we would expect - for Maps and Lists, and not all Collections. If you happen to have a Set implementation as your Collection implementation, for example, it won't work. The empty operator support in JSTL 1.0 is just for null, Strings, arrays, Lists and Maps, not for Sets. It's simply bad, too bad it works this way.

A good reason for people assuming it works like this is that most articles and presentations about JSTL say empty works for Collections. Just to mention a few examples, articles published at OnJava, IBM DeveloperWorks and even
java.sun.com wrongly state it. But why can it simply return true although the spec doesn't mention it? Well, because it cannot be considered an omission. The spec says that otherwise, it must return false. Otherwise sadly covers Sets and any other Collections implementation that does not descend from a List. Sad, very sad indeed.

Are we doomed to look for alternatives approaches? One of them that works is using ${collection['empty']} when we are sure we are dealing with a Collection. Using a straight property access construction won't work as the property has the same name as the reserved operator. Fortunately, the Expression Language definition specified in JSP 2.0 has fixed the issue by replacing the line that mentioned List with:

   Otherwise, if A is an empty Collection, return true,

So, if you are using JSP 2.0, it's not a problem for you. However, be careful about JSTL 1.0 and this bizarre pitfall. I tried to warn you :-D

Related Topics >>