Community
Participate
Working Groups
Hello, I'm having problem with get the real method in case I use the following scenario. class GA<T extends GB> { public void action(Object object) { mService.foo(object); } public void setService (T service) { mService = service; } private T mService; } class GB<T> { public void foo (T param){} } class IMP extends GB<Integer> { @Override @RunAsJob(parameterNames="param", title="A job foo") public void foo (Integer num) { super.foo(num); } } TestClass { testGenericInheritance() { GA ga = new GA<IMP>(); ga.setService(new IMP()); ga.action(new Integer(3)); } } I'm using the following spring <aop> configuration: <bean id="runAsJobAOP" class="jobs.RunAsJobAspect"> <property name="jobManager" ref="jobManager"/> </bean> <aop:config> <aop:aspect ref="runAsJobAOP"> <aop:pointcut id="runAsJobMethod" expression="@annotation(jobs.RunAsJob)" /> <aop:before pointcut-ref="runAsJobMethod" method="handleBefore" /> <aop:after-returning pointcut-ref="runAsJobMethod" method="handleAfter" /> </aop:aspect> </aop:config> class RunAsJobAspect have a method "handlebefore", this method will be called when we are call ga.action(), in the test class, because the method foo within IMP class have annotation @RunAsJob. public void handleBefore (JoinPoint call) { Signature signature = call.getSignature(); if (signature instanceof MethodSignature) { MethodSignature methodSignature = (MethodSignature)signature; } } The problem is that the method signature is of GB.foo() instead of IMP.foo(). Thanks.
On a rudimentary attempt to recreate this with pure AspectJ, it just works - so it'll have to wait until I have time to create a spring testcase. Just to note, this is the code I used that worked: --- import java.lang.annotation.*; import org.aspectj.lang.annotation.*; import org.aspectj.lang.*; import org.aspectj.lang.reflect.*; class GA<T extends GB> { public void action(Object object) { mService.foo(object); } public void setService (T service) { mService = service; } private T mService; } class GB<T> { public void foo (T param){} } class IMP extends GB<Integer> { @Override @RunAsJob(parameterNames="param", title="A job foo") public void foo (Integer num) { super.foo(num); } } public class TestClass { public static void main(String []argv) { GA ga = new GA<IMP>(); ga.setService(new IMP()); ga.action(new Integer(3)); } } @Retention(RetentionPolicy.RUNTIME) @interface RunAsJob { String parameterNames(); String title(); } aspect X { before(): @annotation(RunAsJob) { Signature signature = thisJoinPoint.getSignature(); if (signature instanceof MethodSignature) { MethodSignature methodSignature = (MethodSignature)signature; bSystem.out.println(methodSignature); } } } --- it prints: "void IMP.foo(Integer)"
Thanks Andy, The problem start when I am trying to get the annotation @RunAsJob (for getting the title of the job, I use this code for Job logging). In handleBefore method, my code is: public void handleBefore (JoinPoint call) { Signature signature = call.getSignature(); if (signature instanceof MethodSignature) { Class realInstanceClass = call.getTarget().getClass(); MethodSignature methodSignature = (MethodSignature)signature; realTargetClass.getMethod(methodSignature.getMethod().getName(), methodSignature.getMethod().getParameterTypes()).getAnnotations(); or realTargetClass.getMethod(methodSignature.getMethod().getName(), methodSignature.getMethod().getParameterTypes()).getAnnotation (RunAsJob.class); } } return null in both time, instead of the annotation from IMP class. Until now I used this code with no problem. Is there something wrong in what I have done, or this is a real bug? Thanks, Lior.
sorry I haven't got back to this sooner. I created a simple spring configuration around your scenario. Both the variants of code you included in your last comment worked for me and printed the annotation. Is your annotation definetly RUNTIME retention? If you confirm it is, then maybe I'll share the whole app on here and you can tell me what is different between mine and yours.
Created attachment 149194 [details] My crude test app this is a zip of my testcase. On running it I get: void IMP.foo(Integer) public void IMP.foo(java.lang.Integer) @RunAsJob(parameterNames=param, title=A job foo) @RunAsJob(parameterNames=param, title=A job foo)
removing target whilst waiting on feedback