mardi 22 décembre 2015

Java - Got Exception when Proxy method return type is Future

I'm trying Proxy, implemented InvocationHandler:

public interface IDataInterface {
    public Future<String> getFuture();
}

public class MyData implements IDataInterface {
    private String data = "abc";

    @Override
    public Future<String> getFuture() {
        Callable<String> callMe = () -> {
            TimeUnit.SECONDS.sleep(5);
            return data;
        };
        FutureTask<String> task = new FutureTask<String>(callMe);
        task.run(); // must call run(), or it will block forever!
        return task;
    }
}

public class MyInvocationHandler implements InvocationHandler {
    private final Object delegate;
    private final ExecutorService scheduler;

    public MyInvocationHandler(Object obj) {
        this.delegate = obj;
        scheduler = Executors.newCachedThreadPool();
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        System.out.printf("[Proxy] Will call method: %s\n", method.getName());

        Object result = null;
        if(Future.class.isAssignableFrom(method.getReturnType())) {
            Callable<Object> methodRequest = () -> {
                Object res = method.invoke(delegate, args);
                return res;
            };
            Future<Object> future = scheduler.submit(methodRequest);
            scheduler.shutdown();
            result = future;
        } else {
            result = method.invoke(delegate, args);
        }
        // this will cause definite loop!
        // Object result = method.invoke(proxy, args);
        System.out.println("[Proxy] After method call.");
        return result;
    }
}

In main method, I run:

IDataInterface myData = (IDataInterface)Proxy.newProxyInstance(
                                                        IDataInterface.class.getClassLoader(),
                                                        new Class<?>[] { IDataInterface.class },
                                                        new MyInvocationHandler(new MyData()));
        Future<String> future = myData.getFuture();
        try {
            System.out.println(future.get().toString());
        } catch(InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }

Got following Exception saying java.util.concurrent.FutureTask cannot be cast to java.lang.String:

[Proxy] Will call method: getFuture
[Proxy] Method return type is Future.
[Proxy] After method call.
Get data.Exception in thread "main" java.lang.ClassCastException: java.util.concurrent.FutureTask cannot be cast to java.lang.String
     at others.proxy.Main.main(Main.java:19)

What's the root cause?





Aucun commentaire:

Enregistrer un commentaire