'Can't find referenced pointcut [functionName]

I'm trying to extend an abstract class that contains AspectJ advice. My implementation is very simple:

@Aspect
public class XRayInterceptor extends BaseAbstractXRayInterceptor {
    @Pointcut("execution(public * *(..))")
    private void publicMethods() {}

    @Pointcut("@within(com.amazonaws.xray.spring.aop.XRayEnabled)")
    private void xrayAnnotatedClass() {}

    @Pointcut("xrayAnnotatedClass() && publicMethods()")
    protected void xrayEnabledClasses() {}
}

Unfortunately, when compiling I get the following error from iajc (added line breaks):

[iajc] [error 0]:
    error at com/amazonaws/xray/spring/aop/BaseAbstractXRayInterceptor.java::0
    can't find referenced pointcut xrayEnabledClasses

I can't figure out why it complains about the BaseAbstractXRayInterceptor which is an abstract class and is not being used directly.

For now I simply copied the abstract class, made it concrete and added the pointcuts above to get me unblocked.

Any ideas? Thanks!



Solution 1:[1]

I hate to speculate without an MCVE, so this answer is not definitive, only an educated guess for now:

Looking at the BaseAbstractXRayInterceptor source code, ...

public abstract class BaseAbstractXRayInterceptor {
  // (...)

  @Around("xrayTracedClasses() || xrayEnabledClasses()")
  public Object traceAroundMethods(ProceedingJoinPoint pjp) throws Throwable {
    return this.processXRayTrace(pjp);
  }

  // (...)

  @Pointcut("execution(* XRayTraced+.*(..))")
  protected void xrayTracedClasses() {}

  // (...)
}

I can see that the base class is not declared to be an @Aspect, i.e. it cannot be compiled with the native AspectJ compiler or used by AspectJ as the base class for another native aspect. Update: AspectJ requires its base class to also be an aspect. Without the @Aspect declaration in the base class however, that rule is violated. What we see here, would therefore only work in Spring AOP. The package name com.amazonaws.xray.spring.aop is also suggestive of Spring AOP, even though it does not prove anything.

You however for some reason seem to be trying to use the AspectJ compiler in order to compile your own aspect, obviously using the corresponding Ant task. (I would suggest Maven instead, but that is off-topic here.) The AspectJ compilation step in this case is not just unnecessary but also counter-productive.

I think, you should rather just use your aspect in Spring AOP, assuming you are working in a Spring context. The aspect can be picked up by component scan if you add a @Component annotation to your XRayInterceptor aspect. Otherwise, you can also declare a @Bean factory method instantiating the aspect, but that is more tedious. I do recommend component scan.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1