Details
-
Bug
-
Status: Closed
-
Minor
-
Resolution: Fixed
-
1.7-beta-1, 1.6.5
-
None
-
Ubuntu (Linux) 9.04, x86_64; java 1.6.0_16 (64-bit)
Description
Given:
- a TreeSet or TreeMap with a custom comparator
- elements in the set/map that do not implement Comparable (for example, map literals, which are LinkedHashMap instances)
Calling coll.grep or coll.findAll can raise ClassCastException (really, raised from TreeSet.add).
Note that the exception only arises if grep/findAll matches two or more entries.
I have attached a sample script that meets these criteria and demonstrates the issue.
$ groovy -v
Groovy Version: 1.6.4 JVM: 1.6.0_16
$ java -version
java version "1.6.0_16"
Java(TM) SE Runtime Environment (build 1.6.0_16-b01)
Java HotSpot(TM) 64-Bit Server VM (build 14.2-b01, mixed mode)
$ groovy test.groovy
Caught: java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to java.lang.Comparable
at test.run(test.groovy:9)
Analysis:
Grep lives at:
http://svn.codehaus.org/groovy/branches/GROOVY_1_6_X/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
Which calls createSimilarOrDefaultCollection in:
http://svn.codehaus.org/groovy/branches/GROOVY_1_6_X/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethodsSupport.java
Which calls createSimilarCollection and then createSimilarSet in the same file.
The createSimilarSet method does not copy over the comparator from the original SortedSet. Further, createSimilarMap suffers the same limitation.
Workaround:
The issue can be avoided by converting the original collection to a list using toList() before grepping.