Re: Dynamic proxy causes downstream code to not find annotations. How
to solve?
On Monday, March 16, 2015 at 12:10:53 PM UTC, rupert...@googlemail.com wrot=
e:
Hi,
Consider this class:
class MyClass {
@MyAnnotation
public void myMethod() { ... }
}
Which is coerced to this interface:
interface SomeIterface {
public void myMethod() { ... }
}
If downstream code is looking for "MyAnnotation" it will not find it when=
using a dynamic proxy.
Here is a "default" dynamic proxy, which effectively does nothing except =
to call the method and report its exceptions as normal:
public Object invoke(Object proxy, Method method, Object[] args) throw=
s Throwable {
try {
return method.invoke(obj, args);
} catch (InvocationTargetException e) {
throw e.getCause();
}
}
The problem is that when invoke is called the Method passed to it is the =
one from the interface, not the object, so it is SomeInterface.myMethod(), =
which does not have any annotations.
What I want is to try to match the method on the actual object being prox=
ied, or perhaps some specific interface that I have identified, and effecti=
vely "lift" the actual method being invoked, to being that one.
I am running into this problem because I am using the client proxy from J=
ersey, which uses a dynamic proxy to create a REST client for me, given an =
HTTP endpoint and an interface. The problem is that when you call it, it ch=
ecks that there is a @Path annotation on the method being called, and in th=
is case that method is on a different interface, and it fails to find the a=
nnotation. So I need to make sure that I call it with the method from the c=
orrect interface.
Any suggestions? A problem you have run into before? Thanks for your thou=
ghts.
Rupert
Looking into this some more, I ran this code:
public class QuickTest {
public static void main(String[] args) {
for (Method method : Test.class.getMethods()) {
System.out.println(method);
}
}
}
class Test implements ITest<Integer> {
public Integer someMethod() {
return 1;
}
}
interface ITest<T> {
T someMethod();
}
And got this output:
public java.lang.Integer org.mygovscot.stars.client.Test.someMethod()
public java.lang.Object org.mygovscot.stars.client.Test.someMethod()
(... other methods on Object)
This is actually the problem in my code. The dynamic proxy gets the method =
with types erased, which corresponds to the one on the interface, so it fai=
ls to see the annotations.
I am surprised, because I thought that type erasure would mean that there w=
ould only be one method at run time, not two.
Is there some way to ensure the dynamic proxy picks up the right method?
Rupert