Summary: | Problem getting the real method when using generic classes in Java | ||||||
---|---|---|---|---|---|---|---|
Product: | [Tools] AspectJ | Reporter: | Lior Haham <liorhaham> | ||||
Component: | Runtime | Assignee: | aspectj inbox <aspectj-inbox> | ||||
Status: | NEW --- | QA Contact: | |||||
Severity: | normal | ||||||
Priority: | P3 | CC: | aclement, liorhaham | ||||
Version: | unspecified | ||||||
Target Milestone: | --- | ||||||
Hardware: | PC | ||||||
OS: | Windows XP | ||||||
Whiteboard: | |||||||
Attachments: |
|
Description
Lior Haham
2009-06-28 07:53:47 EDT
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 |