Search code examples
scalaaopaspectjsbt-aspectj

Scala + AspectJ: if() pointcut expressions


I'm using AspectJ library with sbt-aspectj in my Scala project. I'm trying to write @Pointcut with if() expression:

@Aspect
object PerformanceTracer extends Logger {

  @Pointcut("@annotation(PerformanceTracing) && execution(* *(..)) && if()")
  def tracePerfPc(jp: ProceedingJoinPoint): Boolean = {
    // some logic
  }

  @Around("tracePerfPc(jp)")
  def tracePerformance(jp: ProceedingJoinPoint): Object = {
    val start = System.currentTimeMillis
    log.debug("{}: start proceeding", jp.toShortString)
    val res = jp.proceed
    val duration = System.currentTimeMillis - start
    log.info("[{} ms] {}: end proceeding. Duration: {} ms.", duration, jp.toShortString, duration)
    res
  }
}

But I have the following exception:

[warn] warning at <Unknown>::0 Found @Pointcut on a method not returning 'void' or not 'public static boolean'
[error] error at <Unknown>::0 Cannot read debug info for @Aspect to handle formal binding in pointcuts (please compile with 'javac -g' or '<javac debug='true'.../>' in Ant)
[error] org.aspectj.bridge.AbortException: AspectJ failed
[error]         at com.lightbend.sbt.SbtAspectj$Ajc$.runAjcMain(SbtAspectj.scala:212)
[error]         at com.lightbend.sbt.SbtAspectj$Ajc$.runAjc(SbtAspectj.scala:124)
[error]         at 
...

The following AspectJ tutorial says:

It is thus possible with the annotation style to use the if() pointcut only within an @Pointcut expression. The if() must not contain any body. The annotated @Pointcut method must then be of the form public static boolean and can use formal bindings as usual

Is it possible to use if() expression in @Pointcut on Scala methods?


Solution

  • Please note that your method signature for tracePerfPc() is

    def tracePerfPc(jp: ProceedingJoinPoint): Boolean
    

    or more complete

    def tracePerfPc(jp: ProceedingJoinPoint): scala.Boolean
    

    The type Boolean (or scala.Boolean) in scala is not the same as the Java boolean which is a primitive type and no object.

    So you cannot use if() in AspectJ together with a return value as the primitive type boolean does not exists in native scala.