Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

getParameterAnnotations returning empty array

I'm implementing an AOP-based validation mechanism for method arguments. When I specify @NotNull annotation to a method argument I make sure that it's not null or throw exception.

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface NotNull
{

}

Target Spring bean annotated method

@Override
    public PagedCollection<Result> findByRange(@NotNull BigInteger start, @NotNull BigInteger end)
    {
        if (start.compareTo(end) > 0)
            throw new IllegalArgumentException("a > b"); // I haven't yet created an annotation for that

        ...
    }

Aspect code

@Before("execution(public * myapp.managers.spring.*.*(..))")
public void before(JoinPoint jp) throws Throwable
{
    MethodSignature signature = (MethodSignature) jp.getSignature();
    Method method = signature.getMethod();

    before(method, jp.getArgs(), jp.getTarget());
}

public void before(Method method, Object[] args, Object target)
        throws Throwable
{
    Annotation[][] methodAnnotations = method.getParameterAnnotations();

    if (args != null)
    {
        for (int i = 0; i < args.length; i++)
        {
            for (Annotation annotation : methodAnnotations[i])
            {
                if (annotation.annotationType() == NotNull.class)
                    if (args[i] == null)
                        throw new IllegalArgumentException(...);
            }

        }

    }
}

I tried to invoke findByRange with a null argument and debugging. Debug shows that the joinpoint is activated, but method.getParameterAnnotations() returns an empty array for each parameter, like parameters are not annotated.

How to fix?

like image 587
usr-local-ΕΨΗΕΛΩΝ Avatar asked Aug 02 '26 13:08

usr-local-ΕΨΗΕΛΩΝ


1 Answers

Working solution found

Since I have used the manager-implementation design patter (as you can see my bean method is annotated @Override) I found that the way to let the @NotNull annotation work is to annotate the parameter on the interface, and not in the concrete implementation

public interface {
    public PagedCollection<Result> findByRange(@NotNull BigInteger start, @NotNull BigInteger end);
}


public class MyServiceImpl implements MyService
    @Override
    public PagedCollection<Result> findByRange(BigInteger start, BigInteger end)
    {
        if (start.compareTo(end) > 0)
            throw new IllegalArgumentException("a > b"); // I haven't yet created an annotation for that

        ...
    }
}
like image 146
usr-local-ΕΨΗΕΛΩΝ Avatar answered Aug 04 '26 04:08

usr-local-ΕΨΗΕΛΩΝ



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!