I have have a name of an interface and I want to invoke a method defined by its concrete implemented class. So I took help of Java Reflection.
The interface:
package tsb.learning.reflection;
public interface IAnyThing {
void doSomething();
}
It's implemented class:
package tsb.learning.reflection;
public class AnyThing implements IAnyThing {
public void doSomething() {
System.out.println("JYM");
}
}
The implementation of InvocationHandler:
package tsb.learning.reflection;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class AnyInvocationHandler implements InvocationHandler {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return method.invoke(proxy, args);
}
}
And the Controller:
package tsb.learning.reflection;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class Controller {
/**
* @param args
* @throws ClassNotFoundException
*/
public static void main(String[] args) throws ClassNotFoundException {
String interfaceName = "tsb.learning.reflection.IAnyThing";
ClassLoader classLoader = Class.forName(interfaceName).getClassLoader();
Class<?>[] interfaces = new Class<?>[] { Class.forName(interfaceName) };
InvocationHandler handler = new AnyInvocationHandler();
IAnyThing anyThing = (IAnyThing) Proxy.newProxyInstance(classLoader, interfaces, handler);
anyThing.doSomething();
}
}
But it is not working and I am getting the following exception:
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at tsb.learning.reflection.AnyInvocationHandler.invoke(AnyInvocationHandler.java:10)
at $Proxy0.doSomething(Unknown Source)
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at tsb.learning.reflection.AnyInvocationHandler.invoke(AnyInvocationHandler.java:10)
at $Proxy0.doSomething(Unknown Source)
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at tsb.learning.reflection.AnyInvocationHandler.invoke(AnyInvocationHandler.java:10)
at $Proxy0.doSomething(Unknown Source)
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at tsb.learning.reflection.AnyInvocationHandler.invoke(AnyInvocationHandler.java:10)
The exception is printing in console in loop, I need to stop the program.
Any information will be very helpful to me.
Caused by: java.lang.reflect.InvocationTargetException
This mean the method you called threw an exception. You need to look at the exception which appears after it and cause this one. It has nothing to do with how you called the method.
I suspect you are getting a StackOverflowError
// calls the same method on the same proxy which will recurse until you get an error.
return method.invoke(proxy, args);
Instead try calling a method on a real object to do something.
public class AnyInvocationHandler implements InvocationHandler {
final IAnyThing iat;
public AnyInvocationHandler(IAnyThing iat) {
this.iat = iat;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// call the same method on a real object.
return method.invoke(iat, args);
}
}
BTW You can write
Class interfaceClass = tsb.learning.reflection.IAnyThing.class;
ClassLoader classLoader = interfaceClass.getClassLoader();
Class<?>[] interfaces = new Class<?>[] { interfaceClass };
Inside your AnyInvocationHandler, you could delegate the call to an instance of your AnyThing:
public class AnyInvocationHandler implements InvocationHandler {
private AnyThing delegate = new AnyThing();
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// to something useful here
[...]
// finally, invoke the method on implementation class.
return method.invoke(delegate, args);
}
}
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