I need to capture a method call in Java and I do not want to use JPDA or JDI; I want it to happen in the original JVM.
For instance:
public class A {
public void m() {}
}
public class Main {
public static void main(String[] args) {
A a = new A();
a.m();
}
}
I do not want to actually let the method execute at the time, but need to capture it and schedule it in a queue. Thus, AOP will not help me in this regard. I thought about proxying the method. Something such as:
public class A {
public void m() {
methodQueue.add(new MethodInvocation() {
public void invoke() {m_orig();}
});
}
private void m_orig(){}
}
Any ideas? Thanks so much in advance.
The calling method is the method that contains the actual call. The called method is the method being called. They are different. They are also called the Caller and the Callee methods. For example int caller(){ int x=callee(); } int callee(){ return 5; }
Defining Interceptors The preferred way to define in Java code is by using meta-data annotations. They can be defined in the application descriptor as well, but, in that case they are not portable across Java EE servers. Some of the meta-data annotations found in the javax.
You can use a technique called Dynamic Proxies in Java. They are described in detail in the following document: Dynamic Proxies
The solution for your problem would then be (with little changes necessary):
public interface A { void m(); }
public class AImpl implements A { public void m() {} }
public class EnqueueProxy implements java.lang.reflect.InvocationHandler {
private Object obj;
public static Object newInstance(Object obj) {
return java.lang.reflect.Proxy.newProxyInstance(
obj.getClass().getClassLoader(),
obj.getClass().getInterfaces(),
new EnqueueProxy(obj));
}
private EnqueueProxy(Object obj) {
this.obj = obj;
}
public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
try {
MethodQueue mq = ... // get the queue from where you want
mq.add(new MethodInvocation(obj, m, args)
} catch (InvocationTargetException e) {
throw e.getTargetException();
} catch (Exception e) {
throw new RuntimeException("unexpected invocation exception: " + e.getMessage());
}
return null;
}
}
Then construct a EnqueueProxy for an implementation of the A interface and call the m method:
A a = (A) EnqueueProxy.newInstance(new AImpl());
a.m();
Looks like you would also be happy with a queue of Callables.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With