Edit: Bug has been filed.
Let's say I have two ArrayLists that point to each other (circular reference):
x = createObject("java", "java.util.ArrayList").init();
y = createObject("java", "java.util.ArrayList").init();
x.add(y);
y.add(x);
If I call hashCode
on any of them, it causes a StackOverflowError
due to the ArrayList implementation. This is to be expected.
However, when I invoke System.identityHashCode
, isn't it supposed to use the Object.hashCode
implementation, which won't follow the elements in an ArrayList and thus won't cause a StackOverflowError
?
Documentation of identityHashCode
states:
Returns the same hash code for the given object as would be returned by the default method hashCode(), whether or not the given object's class overrides hashCode().
In Adobe ColdFusion, this code works fine:
System = createObject("java", "java.lang.System");
System.identityHashCode(x); // returns some integer
System.identityHashCode(y); // returns another integer
(This obviously also works when natively compiled and run with Java.)
In Lucee however, it immediately causes a StackOverflowError
:
lucee.runtime.exp.NativeException: java.lang.StackOverflowError
at java.base/java.util.ArrayList.hashCodeRange(ArrayList.java:627)
at java.base/java.util.ArrayList.hashCode(ArrayList.java:614)
at java.base/java.util.ArrayList.hashCodeRange(ArrayList.java:627)
at java.base/java.util.ArrayList.hashCode(ArrayList.java:614)
[...]
Why is it running the ArrayList implementation of hashCode
here?
Both CFML engines run with the same JVM (HotSpot) and Java version (11) on the same servlet (Tomcat 9). I'd like to understand why they behave differently.