Koloboke icon indicating copy to clipboard operation
Koloboke copied to clipboard

java.lang.ClassCastException in very specific case on compiled ObjIntMap<String>.keySet().retainAll(...)

Open jmassenet opened this issue 6 years ago • 2 comments

Please see the attached file for a test reproducing the behavior: objIntMapRetainAll.zip

This problem happens when using Koloboke compile to implement a ObjIntMap<String> map, and then trying to remove elements using keySet().retainAll(...).

This issue seems to happen when the first element of the backing array needs to be removed.

In the generated source code, this block adds a tombstone element:

if (indexToShift > indexToRemove) {
    firstDelayedRemoved = i;
    keys[indexToRemove] = XXX.Support.ObjHash.REMOVED;
    break closeDeletion;
} 

But then, the check on key existence for each iteration of the loop is:

if ((key = ((String) (keys[i]))) != null) {
    ...
}

So when the check is executed against the REMOVED object, it fails with this exception:

java.lang.ClassCastException: java.lang.Object cannot be cast to java.lang.String
	at koloboke.KolobokeObjIntMapRetainAllTest_StringKeyObjIntMap.retainAll(KolobokeObjIntMapRetainAllTest_StringKeyObjIntMap.java:2120)
	at koloboke.KolobokeObjIntMapRetainAllTest_StringKeyObjIntMap$KeyView.retainAll(KolobokeObjIntMapRetainAllTest_StringKeyObjIntMap.java:353)
	at koloboke.ObjIntMapRetainAllTest.performTest(ObjIntMapRetainAllTest.java:35)
	at koloboke.ObjIntMapRetainAllTest.testWithStringKey(ObjIntMapRetainAllTest.java:16)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252)
	at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141)
	at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
	at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
	at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
	at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
	at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)

The workaround, as demonstrated by the attached project, it just to use a generic ObjIntMap<Object> instead.

jmassenet avatar Mar 02 '18 10:03 jmassenet

thank you dear @jmassenet for pointing this critical problem, take a look here, please: https://github.com/OryxProject/oryx/issues/353

stiv-yakovenko avatar Sep 24 '18 20:09 stiv-yakovenko

Yeah, that explains the correctness problem in Oryx. For now I've unfortunately switched to eclipse collections even though it's a bit slower.

srowen avatar Oct 06 '18 16:10 srowen