I have 1 Interface called A that needs to be implemented by a class I load dynamically after the program start. Lets call it B.
This interface provides x (more than 1) Methods. Lets call em from a() to z().
Now I have to wrap this class for some time measuring and control issues and run it in its own thread to be able to kill it if it takes too long.
Therefore I have invented class C that wraps B because Bdoesn’t implement runnable on its own.
The next part ist the Class the original Program should call. New Class D. D implements interface A as well to hide the whole controlling part from the model.
Now I have to wrap the methods of the interface in D and send them over and Callable to C who unwraps them and executes them on Object B.
Here some example code who I imagined it can be:
public class D implements A {
private C ai;
public D(String aiName) {
ai = new C("trivialKi");
}
private void call(parameters, ORIGIN_METHOD origin) {
AiTaskExecutor task = new AiTaskExecutor(parameters, origin, ai);
FutureTask<Long> tsk = new FutureTask<Long>(task);
Thread thread = new Thread(tsk);
thread.start();
if (abort) {
tsk.cancel(true);
}
}
@Override
public void a(g g, f f, t t) {
call(g, f, t, ORIGIN_METHOD.a);
}
@Override
public void b(g g, t t, h h) {
call(g, t, h, ORIGIN_METHOD.b);
}
@Override
public void c(g g, t t, f f) {
call(g, t, f, ORIGIN_METHOD.c);
}
}
And in class C the obvious switch case with that enum to pass the parameters to the right method on the class B that is held in class C als private field.
Dou you have a better solution in mind?
I personally don’t like the enum thing and if the parameters are too different this does not work very well.
Is there a “standard” solution for things like that?
The standard solution for this is: Use a “Dynamic Proxy” (
java.lang.reflect.Proxy) for A. This saves you almost all your boilerplate code.This site and Google contains enough usage examples for
Proxy.Also: I propose not to use a new thread for each call – this is extremely expensive if the called methods are short. You can use the
Callableinterface insteadRunnableand a threadpoolExecutorinstead. This also allows you to have return values in your interface 🙂EDIT
Just for fun I coded the dynamic proxy and the executor thing.
Given the following interface
Aand a sample implementationB:A proper
Callableusing reflection to call anyjava.lang.reflect.Methodlooks like this:The part where such a
ReflectiveMethodCallableis created and given to anExecutorServiceis theInvocationHandlerofjava.lang.reflect.Proxy:The
InvocationHandleris used when creating a newProxyincreateProxyFor. The rest of theMainclass is used for a SSCCE example:The output:
To finish up:
Awill be called in another thread.invokeor incall.