Я встречаюсь с причудливой проблемой на сервере JBoss, где два класса создают один и тот же 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()));
Выдает:
fnq.Class1
fnq.Class2
494722
494722
494722
494722
false
false
true
Мне обычно все равно, но мы используем фреймворк, который кэширует сеттеры, используя ключ, состоящий из хэш-кодов из класса и имени свойства. Это плохой дизайн для кэширования, но сейчас он не поддается контролю (OGNL 3.0.6 в последней версии Struts 2.3.24, см. источник. Новый OGNL исправляет но он не будет в Struts до 2.5, в настоящее время в бета-версии.)
Что делает проблему несколько странной для меня, это
- Проблема появляется после нескольких дней использования... и я уверен, что оба класса/свойства становятся кэшированными в течение этого времени. Это заставляет меня поверить, что hashcode экземпляра класса фактически меняется... они стали равными через несколько дней.
- Мы наблюдали поведение в очень устаревшем Hotspot 1.6, а теперь на 1.7.0_80. Оба являются 32-битными строками на Sun Sparc
- Отчеты JVM -XX: hashCode как "0"
Я прочитал, что генератор hashcode RNG в Hotspot (стратегия "0" ) может создавать дубликаты, если есть гоночные потоки, но я не могу себе представить, что загрузка классов вызывает это поведение.
Использует ли Hotspot специальную обработку hashcode при создании экземпляра Class
?