The answers here were useful to explain the problem but it did not help me diagnose why it was happening when I thought I was loading the right JSTL versions. Ultimately I had to debug the application and put a breakpoint in the TLD file processor (maybe org.apache.jasper.compiler.TagLibraryInfoImpl.getTagLibraryInfos()
) to see from where it was getting the TLD files.
I then discovered that it was loading old versions of the TLD files from a jar that I did not suspect had them -- it was a dependency of the GWT (ick) subsystem. Once the offending jar was removed from my maven dependencies, the problem was resolved.
Hopefully this will help someone else in the future.