I'm encountering a bizarre issue on a JBoss server where two classes are producing the same hashCode()
.
Class<?> cl1 = Class.forName("fqn.Class1");
Class<?> cl2 = Class.forName("fqn.Class2");
out.println(cl1.getCanonicalName());
out.println(cl2.getCanonicalName());
out.println(cl1.hashCode());
out.println(cl2.hashCode());
out.println(System.identityHashCode(cl1));
out.println(System.identityHashCode(cl2));
out.println(cl1 == cl2);
out.println(cl1.equals(cl2));
out.println(cl1.getClassLoader().equals(cl2.getClassLoader()));
Produces:
fnq.Class1
fnq.Class2
494722
494722
494722
494722
false
false
true
I normally wouldn't care, but we're using a framework that caches setters using a key that is comprised of hashcodes from the class and a property name. It's a bad design for caching, but it's beyond my control at the moment (OGNL 3.0.6 in the latest Struts 2.3.24, see source. A newer OGNL fixes the issue, but it won't be in Struts until 2.5, currently in beta.)
What makes the issue somewhat bizarre to me is
- Problem appears after several days of usage... and I'm pretty sure both class/properties are getting cached during that time. This leads me to believe that the class instance hashcode is actually changing... they became equal after several days.
- We've observed the behavior in a very outdated Hotspot 1.6, and now on 1.7.0_80. Both are 32-bit builds on Sun Sparc
- JVM reports -XX:hashCode as "0"
I read that the RNG hashcode generator in Hotspot (the "0" strategy) can produce duplicates if there's racing threads, but I can't imagine classloading triggering that behavior.
Does Hotspot use special hashcode handling when creating a Class
instance?