4 Replies Latest reply on Jun 30, 2006 11:10 AM by acxjbertr

    Get annotation information from inside interceptor

    acxjbertr

      I have an EJB (JSR-109) that is annotated with @Timing (a custom annotation I created). I have a pointcut bound to an interceptor that picks up all method invocations with that annotation. All of this works great. However, I added a property to my annotation that I would like to read inside my interceptor. Here is my annotation:

      @Target({ElementType.METHOD})
      public @interface Timing {
       String type() default "[default]";
      }


      Inside my interceptor's invoke method (which is automatically called) I tried:

      public Object invoke(Invocation invocation) throws Throwable {
       String type = (String) invocation.getMetaData("Timing", "type");
      ...
      


      but the result of that call is null. When I look at the invocation object in the debugger, the "metadata" is null.

      How do I get my annotation information from within my interceptor?

        • 1. Re: Get annotation information from inside interceptor
          kabirkhan

          If you annotated the class, use

          Timer ann = invocation.resolveClassAnnotation(Timer.class)
          


          If you annotated a field/method/constructor, use
          Timer ann invocation.resolveAnnotation(Timer.class)
          


          You can then access the type attribute
          System.out.println(ann.type());
          



          • 2. Re: Get annotation information from inside interceptor
            acxjbertr

            Kabir,

            When I do what you suggested (which totally makes sense) I am still getting null. Here is what I have been able to tell after downloading the jboss-aop_1.5.0.GA source:

            invocation.resolveAnnotation(Timer.class) jumps into org.jboss.aop.joinpoint.MethodInvocation.resolveAnnotation(Class annotation). Here is that method:
            public Object resolveAnnotation(Class annotation)
            {
            1 Object val = super.resolveAnnotation(annotation);
            2 if (val != null) return val;
            3 if (getAdvisor() != null)
            4 {
            5 val = getAdvisor().resolveAnnotation(getMethod(), annotation);
            6 if (val != null) return val;
            7 }
            8 return null;
            }

            Line 1 returns null therefore line 2 does nothing
            getAdvisor() in line 3 returns non null so that line 5 is executed
            Here is the code for org.jboss.aop.Advisor.resolveAnnotation(Method m, Class annotation):
            public Object resolveAnnotation(Method m, Class annotation)
            {
            01 if (metadataContext != null)
            02 {
            03 Object val = metadataContext.getAnnotation(m, annotation);
            04 if (val != null) return val;
            05 }
            06
            07 if (annotations.isDisabled(m,annotation))
            08 return null;
            09
            10 Object value = annotations.resolveAnnotation(m, annotation);
            11 if (value == null) value = AnnotationElement.getVisibleAnnotation(m, annotation);
            12 return value;
            }

            Interesting note: the "annotations" property on the Method object "m" that is passed into this method is null
            Line 01 doesn't do anything because the metadataContext is null
            Line 07 doesn't do anything because no annotations are "disabled"
            Line 10 doesn't do anything because the "annotations" property on "m" is null
            Line 11 is interesting. Because I am using JDK 1.5 it doesn't actually invoke AnnotationElement.getVisibleAnnotation(m, annotation). Instead it invokes Method.getAnnotation(Class annotationClass) which tries to get the "declaredAnnotations" list, which is empty, so it does nothing
            therefore null is returned to org.jboss.aop.joinpoint.MethodInvocation.resolveAnnotation(Class annotation) which in turn returns null to invocation.resolveAnnotation(Timer.class)


            Is this expected behavior?

            • 3. Re: Get annotation information from inside interceptor
              kabirkhan

              Make sure that you set the @Retention on your annotation so that it is available at runtime

              @Retention(RetentionPolicy.RUNTIME)
              @Target({ElementType.METHOD})
              public @interface Timing {
               String type() default "[default]";
              }
              


              • 4. Re: Get annotation information from inside interceptor
                acxjbertr

                That was it! Thanks for your timely and accurate responses, Kabir.

                If I may, I would suggest that an example like this be added to the AOP documentation.