3

From the following previous question (AspectJ - Presence of annotation in join point expression not recognized),

My goal: In an aspect, i'd like to be able to extract/retrieve all annotated parameters from matching functions, no matter how many there are. (and then apply some treatment on but it's not the scope of this question)

So for the moment, this is what i did (not working):

@Before("execution (* org.xx.xx.xx..*.*(@org.xx.xx.xx.xx.xx.Standardized (*),..))")
public void standardize(JoinPoint jp) throws Throwable {
    Object[] myArgs = jp.getArgs();
    getLogger().info("Here: arg length=" + myArgs.length);
    // Roll on join point arguments
    for (Object myParam : myArgs) {

        getLogger().info(
                    "In argument with " + myParam.getClass().getAnnotations().length
                                + " declaread annotations");
        getLogger().info("Class name is " + myParam.getClass().getName());
        // Get only the one matching the expected @Standardized annotation
        if (myParam.getClass().getAnnotation(Standardized.class) != null) {
            getLogger().info("Found parameter annotated with @Standardized");
            standardizeData(myParam.getClass().getAnnotation(Standardized.class), myParam);
        }
    }
}

This is the code matched by the advice:

public boolean insertLog(@Standardized(type = StandardizedData.CLIPON) CliponStat theStat) {
    // ...
}

And the traces generated by a junit test:

INFO: ICI: arg lenght=1
INFO: In argument with 0 declaread annotations

Looks like it doesn't detect the annotation

So my question is: how to detect parameters which have specific annotation(s) ?

Does somebody have an idea how to do it?

Thanks in advance for your help.

Regards.

Edit: i found this thread Pointcut matching methods with annotated parameters, discussing of the same thing, and applied the given solution but it doesn't work..

Community
  • 1
  • 1
kij
  • 1,421
  • 1
  • 16
  • 40

1 Answers1

20

I hope I understand you right.

myParam.getClass().getAnnotations() gives you the annotations on a class. Something like:

@Standardized(type = StandardizedData.CLIPON)
public class Main{...}

Maybe this pointcut/advice helps you:

@Before("execution (* org.xx.xx.xx..*.*(@org.xx.xx.xx.xx.xx.Standardized (*),..))")
public void standardize(JoinPoint jp) throws Throwable {
    Object[] args = jp.getArgs();
    MethodSignature ms = (MethodSignature) jp.getSignature();
    Method m = ms.getMethod();

    Annotation[][] parameterAnnotations = m.getParameterAnnotations();

    for (int i = 0; i < parameterAnnotations.length; i++) {
        Annotation[] annotations = parameterAnnotations[i];
        System.out.println("I am checking parameter: " + args[i]);
        for (Annotation annotation : annotations) {
            System.out.println(annotation);

            if (annotation.annotationType() == Standardized.class) {
                System.out.println("we have a Standardized Parameter with type = "
                        + ((Standardized) annotation).type());
            }
        }
    }
}

This gives me the following output:

I am checking parameter:  main.CliponStat@331f2ee1 
@annotation.Standardized(type=CLIPON)
we have a Standardized Parameter with type = CLIPON
kriegaex
  • 63,017
  • 15
  • 111
  • 202
Fred
  • 446
  • 3
  • 5
  • Hi Fred, yep you're right. That is what i finally implemented yesturday evening. It was not working at the beginning, but because i made another mistake (i annotated the parameters in the method in both the interface and the implementation class, and it seems to parasite the normal behaviour. I've removed the annotation from the interface and it works fine. Thanks for your help. – kij May 15 '12 at 08:05
  • One additional gotcha: the annotation class itself (in this example, `@Standardized`) must be annotated with `@Target({ElementType.PARAMETER})` or equivalent for the `getParameterAnnotations()` method to pick it up. – Mark Jun 24 '22 at 13:02
  • good example, thanks @kriegaex – nobjta_9x_tq Jun 10 '23 at 08:17