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

imap.setAsync throws an erroneous java.lang.ClassCastException inside the returned iCompletableFuture #9599

Closed
vmarquez opened this issue Jan 7, 2017 · 4 comments · Fixed by #9600
Labels
Source: Community PR or issue was opened by a community user Team: Core Type: Defect
Milestone

Comments

@vmarquez
Copy link
Contributor

vmarquez commented Jan 7, 2017

We are using Hazeclast version 3.7.4.
Java(TM) SE Runtime Environment (build 1.8.0_60-b27)

We use Hazelcast with Scala, but I don't believe the issue has anything to do with that. Here is a simple bit of code to replicate the problem.

import com.hazelcast.core.Hazelcast
import com.hazelcast.core.HazelcastInstance
import com.hazelcast.config._
import com.hazelcast.core._

object HazelcastTest {
  
  val hz = Hazelcast.newHazelcastInstance()
  val hazelcastMap: com.hazelcast.core.IMap[String, Int] = hz.getMap("mymap")
  val f: ICompletableFuture[Void] = hazelcastMap.setAsync("a", 5)
   //throws an Exception
  f.andThen(new ExecutionCallback[Void]() { override def onResponse(a: Void): Unit = println("HELLO WORLD"); 
  override def onFailure(t: Throwable): Unit = println("failure = " + t);
  }) 

  val fp: ICompletableFuture[Int] = hazelcastMap.putAsync("a", 5)
  //works as expected
  fp.andThen(new ExecutionCallback[Int]() { override def onResponse(a: Int): Unit = println("HELLO WORLD i =" + a); 
  override def onFailure(t: Throwable): Unit = println("failure = " + t);
  })
}

setAsync's onResponse is called but before the callback can be run the following Exception is thrown:

java.lang.ClassCastException: java.lang.Boolean cannot be cast to java.lang.Void                                                                                                                                                                                                              
at $sess.cmd9$$anon$1.onResponse(cmd9.sc:1)                                                                                                                                                                                                                                           
at com.hazelcast.util.executor.DelegatingFuture$DelegatingExecutionCallback.onResponse(DelegatingFuture.java:172)                                                                                                                                                                     
at com.hazelcast.spi.impl.AbstractInvocationFuture$1.run(AbstractInvocationFuture.java:251)                                                                                                                                                                                           
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)                                                                                                                                                                                                    
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)                                                                                                                                                                                                    at java.lang.Thread.run(Thread.java:745)                                                                                                                                                                                                                                              
at com.hazelcast.util.executor.HazelcastManagedThread.executeRun(HazelcastManagedThread.java:76)                                                                                                                                                                                      
at com.hazelcast.util.executor.HazelcastManagedThread.run(HazelcastManagedThread.java:92)         

However, the set did succeed and I can see my values inside the map.

@pveentjer
Copy link
Contributor

I checked the code and I do see that the SetOperation returns a boolean.

public class SetOperation extends BasePutOperation {

    private boolean newRecord;

    @Override
    public void run() {
        newRecord = recordStore.set(dataKey, dataValue, ttl);
    }

    @Override
    public Object getResponse() {<------
        return newRecord;
    }
}

So it explains you running into the ClassCastException.

Here is a java reproducer:

public class Main {

    public static void main(String[] args){
        HazelcastInstance hz = Hazelcast.newHazelcastInstance();
        IMap map = hz.getMap("map");
        ICompletableFuture a = map.setAsync("1", "a");

        a.andThen(new ExecutionCallback() {
            @Override
            public void onResponse(Object response) {
                System.out.println("response.class = "+response.getClass().getName());
            }

            @Override
            public void onFailure(Throwable t) {

            }
        });
    }
}

My big question is why the Set Operation is returning a response. I guess it is related to updating internal on completion like statistics.

@pveentjer
Copy link
Contributor

pveentjer commented Jan 7, 2017

For the time being, can you run with an untyped future? If the future is returning void; then you are not interested in a result value anyway.

@vmarquez
Copy link
Contributor Author

@pveentjer There isn't really a way to do that as the return type of setAsync is the parameterized over Void. I can use putAsync for now. Thanks for your quick response and identifying the offending code!

@pveentjer
Copy link
Contributor

the putAsync will be a bit more expensive than the set because the put will return the old value. So there is more network traffic + deserialization involved.

I'm going to close this ticket since the fix will be in the latest maintenance release which should be released one of these days.

@jerrinot jerrinot added this to the 3.7.5 milestone Jan 19, 2017
@mmedenjak mmedenjak added the Source: Community PR or issue was opened by a community user label Sep 2, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Source: Community PR or issue was opened by a community user Team: Core Type: Defect
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants