JSTL empty operator

A teammate and I were foiled by an interesting JSTL quirk this week. The code looked something like this

<c:if test="${not empty aquarium.fish}">
    <!---- feed the fish or something ---->
</c:if>

THE PROBLEM

The problem was, the fish were being fed whether the aquarium was empty or not.

The code

<c:if test="${!empty aquarium.fish}">

behaved the same, weird way. But we were sure, either way, that our syntax was correct. So that leaves only one question: WTF?

We know that we’re receiving an instance of aquarium from a method call developed by another team. We know that getFish() returns a java.util.Collection. Other than that we don’t care about the implementation, we just want our fish. In theory.

So we dug into the code for the other team’s getFish() method, and found out that our Collection is actually implemented as a HashSet. And JSTL behaves a little weird with respect to the empty operator: it does not work with java.util.Set. Incidentally this isn’t a problem in JSTL 1.1 or 1.2, and unfortunately we’re stuck using JSTL 1.0 for now. So unfortunately this forces us to know how this Collection is implemented in order to know how to handle it.

WHY?

As of JSTL 1.1, “… the Expression Language now belongs to the JSP specification (JSP 2.0).” [from the JSTL 1.1 spec]

Since versions numbers don’t always line up such that it’s clear what is compatible with what, here’s a view of which JSTL versions go with which JSP versions:

JSTL 1.0>JSP 1.3;  JSTL 1.1>JSP 2.0;  JSTL 1.2>JSP 2.1;

Now let’s compare the specs for the empty operator

From the JSTL 1.0 Spec:

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.

From the JSP 2.0 and 2.1 Spec, which are identical in this regard:

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 Collection, return true,
  • Otherwise return false.

The difference is the last comparison. The older version uses the List interface, the newer uses Collection interface. List is a sub-interface of Collection, so anything that’s a Collection but not also a List will not work in JSTL 1.0. For example:

  • The “empty” keyword in JSTL will work for things like List, ArrayList, LinkedList, Vector, etc.
  • The “empty” keyword in JSTL will not work for Set, HashSet, TreeSet, etc.

REFACTOR

There’s 2 options around this.

1: upgrade.

2: If that’s not an option, there is another workaround.

The nice thing about “empty” is that it will check for both null and empty lists for you. Our workaround had to be a little more verbose:

<c:if test="${aquarium.fish != null && !aquarium.fish['empty']}">
    <!---- feed the fish or something ---->
</c:if>
Posted in code. Tags: . 11 Comments »

A Whirlwind of Good Ideas

Welcome to my blog. What’s this all about? What is the purpose and focus here? I’m glad you asked.

I recently attended the 2008 CodeMash conference, and have thus been inspired to try my hand at a blog with a technical-focus. This is that blog.

I had a great time at CodeMash. I always come away from these events both exhilarated and exhausted. It’s great fun to hang out with existing friends as well as meet new friends, and yet fatiguing to stay up late hanging out with said friends. It is awesome to be a part of some of some interesting and thought-provoking conversations that take place at technical conferences, and yet taxing with all the new information you get from those conversations as well as in the sessions you attend.

And so, that’s where this blog begins. I plan to write summaries of – and perhaps add some of my own insights to – a few of the conversations that stuck out in my mind from CodeMash. This includes, but is not limited to:

  • An exploration of the term “man-crush.”
  • Foreign Languages vs. Computer Languages – similarities and differences between the two.
  • Women in Development – a conversation that begun with Dianne Marsh, and others in proximity joined in, too.

After writing about these, I have a few other ideas up my sleeve as well. I’ll leave those thoughts as a surprise for now. I expect that with the whirlwind of thoughts running around in my head at the moment, my blograte will be a little higher than normal at first. But I hope to slow down to a more steady pace for the long-haul after that.

Stay tuned, and thanks for reading!