Here is an example of my code:
class foo extends afoo{
@HTTPPost
returnClass runTransaction(RequestData req){
return sendData(req, returnClass.class)
}
@HTTPGet
returnClass runTransaction2(RequestData req){
return sendData(req, returnClass.class)
}
}
abstract class afoo {
public <T> T sendData(ARestMessage req, Class<T> returnClassType)
//here i need the annotation of the calling method
}
Basically i'm building a pretty complex messaging system and I want to put as much of the switching and configuration in annotations as i can.
Yes, I know there are a few libraries out there (like Google reflection) that would make this easier but in order for me to use them I have to do 4-6 months of paperwork and meetings with Enterprise Architecture to get approval to use them. Seeing the project must be finished in 2 months, i'm doing it by hand.
So what i'm doing is creating annotations that developers can annotate the methods with indicating the way the resulting service is expecting the data to be sent. That could be a get, post, put, etc. Inside the abstract class, that all service classes extend, is a senddata method. That method must be able to figure out which method was used to call it, aka, was it by runTransaction or runTransaction2, so sendData pull that methods annotations and therefore know exactly how to send the data to the service.
now I found this (which is the first line of code in my sendData method)
final Method callingMethod = this.getClass().getEnclosingMethod();
But it keeps returning null. i've read the javadoc on it several times and i'm not understanding why it keeps returning null.
I understand that I can get the parent caller using the stack, but I would prefer not to do that because this application shares app server memory with another application that does a TON of AOP work. That AOP work is really good at messing up stacks in unintended ways, so I would rather solve this using straight reflection.
Does anyone know why this method keeps returning null? Is it because its contained in an abstract class and not my foo class itself? Is there a way to accomplish this using the techniques I would prefer to use?
thanks
The method Class.getEnclosingMethod() does not do what you think it does. Here is the Javadoc for it:
If this Class object represents a local or anonymous class within a method, returns a Method object representing the immediately enclosing method of the underlying class. Returns null otherwise. In particular, this method returns null if the underlying class is a local or anonymous class immediately enclosed by a type declaration, instance initializer or static initializer.
Specifically, it returns the outer, enclosing method for an anonymous inner class, that was defined in the context of that method. I did not see anywhere in your description that these messaging methods are being called from anonymous/local inner classes. Here is an example in code (jUnit required):
import java.lang.reflect.Method;
import org.junit.Assert;
import org.junit.Test;
interface Introspector {
public Method getEnclosingMethod();
}
public class Encloser {
public Encloser() {
super();
}
public Method noop() {
final Introspector inner = new Introspector() {
@Override
public Method getEnclosingMethod() {
return getClass().getEnclosingMethod();
}
};
return inner.getEnclosingMethod();
}
@Test
public void testEnclosingMethods() throws Exception {
final Encloser encloser = new Encloser();
Method method = encloser.getClass().getEnclosingMethod();
Assert.assertNull(method);
method = encloser.noop();
Assert.assertNotNull(method);
}
}
Your current solution sounds pretty complicated. Are you planning on walking up the method call chain (which you can only do by dumping the stacktrace btw) and looking for annotations after doing some hefty reflection? I foresee alot of bugs. Frankly, employing some kind of builder pattern would probably be better for your scenario.
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