users@jersey.java.net

get(null) on KeyComparatorHashMap does not return null - unlike standard Java Maps

From: Alex Treppass <alextreppass_at_gmail.com>
Date: Fri, 25 Jun 2010 10:27:00 +0100

KeyComparatorHashMap is a Jersey class that appears to operate like a
java.util.HashMap, except that you can specify a helper class to
generate the hashes and equals (so is useful for maps and classes we
have no control over).

We're using one in our authentication to map our user
java.security.Principal objects. The behaviour we're noticing is that
when we do something like:
-------------------
KeyComparatorHashMap<Principal, OurPrincipalStateObject>
principalStates; // assume populated
Principal p; // null in this case
OurPrincipalStateObject state = principalStates.get(p);
if (state == null)
{
    // Anonymous user or not logged in
}
else
{
    // handle logged-in user
}
-------------------

Looking at the Jersey code, it does an internal maskNull() call that
replaces the null with a new Object(). new Object() doesn’t cast to
Principal particularly well and we get a classcast exception, rather
than getting null from the Map.

This behaviour is unlike standard Java Maps, and to get around it we'd
have to insert an extra null check before attempting to retrieve from
the map. Is this intentional?

We're using the vanilla release of Jersey 1.2.

Test case attached.

Alex