Search code examples
javaannotationsaspectj

Getting error error at ::0 formal unbound in pointcut while accessing annotation value inside an advice using ApectJ


I'm trying to access custom annotation value inside an advice method but getting an error

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryConfiguration$EmbeddedTomcat': Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: error at ::0 formal unbound in pointcut 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:610)
Caused by: java.lang.IllegalArgumentException: error at ::0 formal unbound in pointcut

Annotation declaration

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

This issue happening with second argument in the method, if I removed the second argument application starts properly.

@Aspect
@Component
public class AspectHandler{
    @Around(value = "@annotation(com.myorg.authorization.annotations.Authorize)")
    public void AuthValidator(ProceedingJoinPoint point, Authorize authorize) throws Throwable {
        String[] entitlements = authorize.entitlements();
        point.proceed();
    }
}

I tried with argNames argument, still it doesn't work

@Around(value = "@annotation(com.virtana.authorization.annotations.Authorize)", argNames = "authorize")

also tried

@Around(value = "@annotation(com.virtana.authorization.annotations.Authorize) && args=authorize")

Solution

  • Your syntax is wrong. For unbound annotations it would be correct to use the fully qualified class name:

    @Around("@annotation(com.myorg.authorization.annotations.Authorize)")
    public void validate(ProceedingJoinPoint point) throws Throwable
    

    For an annotation bound to an advice method parameter, you only use the parameter name as a reference:

    @Around("@annotation(authorize)")
    public void validate(ProceedingJoinPoint point, Authorize authorize) throws Throwable
    

    By the way: If your around advice returns void, it can only match methods with the same return type. If the target method returns anything else, your advice needs to return the result of proceed() or something other matching the actual return type.

    Please also make sure to adhere to Java naming conventions. AuthValidator looks like a class name. Method names should not be nouns like SomeObject but verbal descriptions like doSomething, starting with a lower-case character.