Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
jmassenet opened this issue Mar 2, 2018 · 2 comments

Comments

@jmassenet
Copy link

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 instead.

@stiv-yakovenko
Copy link

thank you dear @jmassenet for pointing this critical problem, take a look here, please: OryxProject/oryx#353

@srowen
Copy link

srowen commented Oct 6, 2018

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants