7

I have an abstract class called Client. How can I get access to an annotation that was declared on the calling method on the child class? What's the best way to handle this?

public abstract class Client {

   protected void synchronize() {

      // How can I get the Annotation defined on inheriting class?   
      StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
      StackTraceElement lastStackElement =       stackTraceElements[stackTraceElements.length-1] ;
      Method m = this.getClass().getMethod(lastStackElement.getMethodName(),       String.class, int.class);
      m.getAnnotation(Cache.class);

      // synchronize data from server
   }

}

.

public class OrderClient extends Client {

   @Cache(minute = 5)
   public void synchronizrWithCustomerId(String customerId) {

      // So some stuff setup body and header

      super.synchronize();
   }

}
1
  • 1
    probably something along the lines of what you just wrote down. just cache the results by classname+methodname to avoid repeated reflection Commented Dec 27, 2012 at 6:58

2 Answers 2

2

Based on your example this code works well:

public class TestS1 {

    public abstract class Client {

        protected void synchronize() throws NoSuchMethodException {
            // How can I get the Annotation defined on inheriting class?
            StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
            StackTraceElement lastStackElement = stackTraceElements[2];

// take attention here: stackTraceElements[2]

     Method m = this.getClass().getMethod(lastStackElement.getMethodName(), String.class);
            Cache annotation = m.getAnnotation(Cache.class);
            System.out.println("Cache.minute = " + annotation.minute());
            // synchronize data from server
        }
    }

also you need to mark your annotation with @Retention(RetentionPolicy.RUNTIME)

    @Retention(RetentionPolicy.RUNTIME)
    @interface Cache {
        int minute();
    }

    public class OrderClient extends Client {
        @Cache(minute = 5)
        public void synchronizrWithCustomerId(String customerId) throws NoSuchMethodException {
            // So some stuff setup body and header
            super.synchronize();
        }
    }

    public void doTest() throws NoSuchMethodException {
        OrderClient oc = new OrderClient();
        oc.synchronizrWithCustomerId("blabla");
    }

    public static void main(String[] args) throws NoSuchMethodException {
        TestS1 t = new TestS1();
        t.doTest();
    }

}

Output is: Cache.minute = 5

Sign up to request clarification or add additional context in comments.

7 Comments

What does retention do? and is it possible to implement it in 1 place instead of every synchronize method? thanks
@aryaxt Retention(RUNTIME) is needed to provide accessing to your annotaitons in Runtime (see also: stackoverflow.com/questions/2286998/…). I don't understand second part of your question about implementing it in 1 place. If it about Retention, so you need to annotate with it only Cache interface.
I got this error while annotating retention. The annotation @Retention is disallowed for this location.
I didn't find @Json annotation (could you provide URL link?), but for example here they really use Retention(RUNTIME): github.com/FasterXML/jackson-annotations/blob/master/src/main/…
Sorry I was wrong, I realized that Retention should be on annotation class
|
0

Andremoniy answer is absolutely correct. The only thing I changed was the way i lookup in the stack-trace.

    Cache cache = null;

    try {
        StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();

        for (StackTraceElement element : stackTraceElements) {
            if (this.getClass().getName().equals(element.getClassName())) {
                Method method = this.getClass().getMethod(element.getMethodName(), String.class);
                cache = method.getAnnotation(Cache.class);
                break;
            }
        }
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.