Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting the actual class used for a MethodInvocation rather than the declaring class

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.

like image 670
super_seabass Avatar asked Feb 18 '23 11:02

super_seabass


1 Answers

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("...");
    }
like image 127
super_seabass Avatar answered Mar 09 '23 01:03

super_seabass