If you run YAML long enough, it will create random recursive links where
ones shouldn't exist. I guess this is because it assumes
System.identityHashCode() will always return different values for the same
object; this is NOT the case:
$ grep -R "identityHashCode" .
./Yaml.java: this.name = "Yaml:" + System.identityHashCode(this);
./nodes/MappingNode.java:
buf.append(System.identityHashCode(node[1]));
./representer/BaseRepresenter.java: aliasKey =
System.identityHashCode(data);// take memory address
(the comment is wrong, the hashcode *some function* of the memory address
used when the object is *first allocated*)
If it all that's needed is an identity map, you can use IdentityHashMap; it
will keep track of objects correctly even if they have the same
identityHashCode, it will just put them into the same bucket. ie:
representer/BaseRepresenter.java:
protected final Map<Integer, Node> representedObjects = new
HashMap<Integer, Node>();
change this to
protected final Map<Object, Node> representedObjects = new
IdentityHashMap<Object, Node>();
To test this, generate around 2^16 random objects and save them in the same
file. (This is approximately the expected number of hashes needed to see a
collision between any two of them, for a 32-bit sized hash code.)
Original issue reported on code.google.com by infinity0x@gmail.com on 13 Jul 2009 at 9:55
Original issue reported on code.google.com by
infinity0x@gmail.com
on 13 Jul 2009 at 9:55