1

I have following code where my pointcut is based on annotation on interface. It does not work if object variable on caller method is defined as implementation class. But if I cast (same object) it to Interface then it works !!

package sample;
public interface MyInterface {
    @Write //runtime annotation
    public void methodA();
}

// In Write.java file
@Retention(value = RetentionPolicy.RUNTIME)
@Target(value = ElementType.METHOD)
public @interface Write {

}
package sample;
public class MyImpl implements MyInterface {
    public void methodA() {
        System.out.println("MyImpl");
    }
}

And two aspects defined as

@Aspect
public class MySimpleAspect {
    @Around("execution(public * sample.MyImpl.*(..))")
    public Object simpleAround(ProceedingJoinPoint point) throws Throwable {
        
        System.out.println("in Simple Aspect");
        return point.proceed();
      }
}
@Aspect
public class MyComplexAspect {
    @Around("call(@Write * sample.MyInterface+.*(..))")  // doesn't get invoked if <includes> is part of pom
    public Object complexAround(ProceedingJoinPoint point) throws Throwable {
        
        System.out.println("in complex Aspect");
        return point.proceed();
        
    }
}

Test class

package sample;

import org.junit.Test;

public class MyTest {
    
    @Test
    public void testMyImpl() {
        System.out.println("-- Using MyImpl.methodA() ---");
        MyImpl my = new MyImpl(); //does not work
        my.methodA();
        
        System.out.println("\n-- Using myinterface.methodA() ---");
        MyInterface myinterface = my; //works
        myinterface.methodA();
    }
}

Output

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
OpenJDK 64-Bit Server VM warning: ignoring option MaxPermSize=256m; support was removed in 8.0
Running sample.MyTest
-- Using MyImpl.methodA() ---
in Simple Aspect
MyImpl

-- Using myinterface.methodA() ---
in complex Aspect
in Simple Aspect
MyImpl
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.064 sec

UPDATE

Updated question with more code and output and removed pom/maven related stuff as it turns out to be pure aspectj problem and not maven

  • AspectJ version 1.9.6
  • AspectJ Maven Plugin 1.11
  • JDK 1.8
kriegaex
  • 63,017
  • 15
  • 111
  • 202
Jags
  • 799
  • 7
  • 19
  • I do not believe that the Surefire settings as such have influence on the result. Instead, I believe that the tests themselves or the code under test determine, which aspects get triggered. Unfortunately, you left out the exact thing you asked about: the tests + code under test. Not a very good idea. Please edit the question, then notify me by a comment. Thanks. BTW, I have an idea what might be going on, but want to see for myself, not speculate. – kriegaex Jun 27 '21 at 02:05
  • @kriegaex You are right. Its not maven related. But its pure aspectj issue. I updated question with full code, test and output. My pointcut is based on annotation on interface. It does not work if object variable on caller method is defined as implementation class. But if I cast (same object) it to Interface then it works !! Still stuck at same issue. I have no way to control caller. – Jags Jun 28 '21 at 17:19
  • 1
    Thanks for the extra info. It confirms my guess. Please read the Q/A I linked to in order to understand why your aspect works exactly as expected in both cases. There is no such thing as annotation inheritance from interface methods to implementing methods, not even if you would use the `@Inherited` meta annotation on your own annotation class. – kriegaex Jun 29 '21 at 14:41
  • @kriegaex Thanks! I understand that its JVM which does not propagate annotation to child class and aspectj compiler only looks at handle (variable) definition (in my case interface). Is there any way to improve aspectj compiler to do deep search on all parents to see if annotation is present on method? It may be optional feature to turn on at compile weaving time. – Jags Jun 29 '21 at 17:32
  • 1
    Thanks for the update. So the question is a duplicate and already answered, no need to re-open here. As for your AspectJ feature request, I think it would be possible in theory, but considerably slow down pointcut matching and involve extra caching in order to mitigate the performance degradation. I cannot say much about the chances to get that implemented, because it would depend on development resource availability and backlog prioritisation. – kriegaex Jun 30 '21 at 02:42
  • 1
    FWIW, I added [AspectJ issue #78](https://github.com/eclipse/org.aspectj/issues/78), so at least the AspectJ dev team knows that somebody asked about it. – kriegaex Jun 30 '21 at 02:58

0 Answers0