Reputation: 1116
I'm digging through a web application in an effort to fix some problems. The application uses Tomcat, Jersey and Guice. One of the issues is occurring in a MethodInterceptor used for authorization purposes. Here's the method, trimmed to the relevant part:
public Object invoke(MethodInvocation invoc) throws Throwable {
// ...
//Check that the annotation actually exists
if(! invoc.getMethod().getDeclaringClass().isAnnotationPresent(Tool.class))
{
throw new BaseException("...");
}
// ...
}
Now the problem is that some of the "web-facing" methods are inherited from a parent class without being overridden in the child. If I understand getDeclaringClass() correctly, it will return the parent class in this case, but what we really want here is the child class. Some testing seems to confirm this--if I override the method in the child class everything is fine, but if I don't put in the override the exception is thrown.
So, given a MethodInvocation object, is there a way to trace it back to the "actual" class instantiated, rather than the class where the method was declared? Or is some other approach necessary? Worst-case, I could just annotate each method as necessary rather than annotating the class.
Sorry if this is a long-winded question for an easy answer - my Java is pretty rusty.
Upvotes: 4
Views: 5123
Reputation: 1116
Simple enough, needed to use getThis().getClass()
on the MethodInvocation instead of getMethod().getDeclaringClass()
:
if(! invoc.getThis().getClass().isAnnotationPresent(Tool.class))
{
throw new BaseException("...");
}
Although in my case, Guice complicated things a bit by putting in an auto-generated child class (e.g., a class name ending in "$$EnhancerByGuice..." That was fixed by moving one up the tree with getSuperclass()
:
if(! invoc.getThis().getClass().getSuperclass().isAnnotationPresent(Tool.class))
{
throw new BaseException("...");
}
Upvotes: 8
Reputation: 515
It looks like that the answer is No. I created simple test to check it:
class Run implements Runnable {
@Override
public void run() {
}
}
class Run2 extends Run{}
Method method = Run2.class.getMethods()[0];
System.out.println(method);
As we can see in debug window method doesn't have any information of class Run2:
I guess it would be better to stick on actual methods with its annotations rather then on actual class instances where these methods get invoked.
Upvotes: 0