简体   繁体   中英

Is it possible to include classes to be weaved by their annotations on aop.xml?

I'm developing some aspects which are expected to load-time weave classes with @AnAnnotation. I created aop.xml as follows

<!DOCTYPE aspectj PUBLIC "-//AspectJ//DTD//EN" "https://www.eclipse.org/aspectj/dtd/aspectj.dtd">
<aspectj>

    <weaver options="-verbose -showWeaveInfo">
        <include within="@com.example.MyAnnotation *" />
    </weaver>

    <aspects>
        <aspect name="com.example.MyAspect" />
    </aspects>

</aspectj>

and according to log, my aspect seems to try advise appropriate classes but right after that the following exception occurred.

java.lang.NoSuchMethodError: com.example.MyAspect.aspectOf

Any ideas?

:log

[ERROR] [AppClassLoader@2b193f2d] info AspectJ Weaver Version 1.9.7 built on Thursday Jun 24, 2021 at 16:14:45 PDT
[ERROR] [AppClassLoader@2b193f2d] info register classloader jdk.internal.loader.ClassLoaders$AppClassLoader@2b193f2d
[ERROR] [AppClassLoader@2b193f2d] info using configuration project/target/classes/META-INF/aop.xml
[ERROR] [AppClassLoader@2b193f2d] info register aspect com.example.MyAspect
[ERROR] [AppClassLoader@2b193f2d] weaveinfo Join point 'constructor-execution(void com.example.MyAspectTest$MyTargetClass.<init>(com.example.MyAspectTest, java.lang.String))' in Type 'com.example.MyAspectTest$MyTargetClass' (MyAspectTest.java:165) advised by afterReturning advice from 'com.example.MyAspect' (MyAspect.java) [with runtime test]
[ERROR] [AppClassLoader@2b193f2d] weaveinfo Join point 'method-execution(void com.example.MyAspectTest$MyTargetClass.myMethod(int))' in Type 'com.example.MyAspectTest$MyTargetClass.' (MyAspectTest.java:182) advised by afterReturning advice from 'com.example.MyAspect' (MyAspect.java) [with runtime test]
[INFO] Running com.example.MyAspectTest
[ERROR] Tests run: 5, Failures: 0, Errors: 5, Skipped: 0, Time elapsed: 0.055 s <<< FAILURE! - in com.example.MyAspectTest
[ERROR] com.example.MyAspectTest.testMyMethod  Time elapsed: 0.011 s  <<< ERROR!
java.lang.NoSuchMethodError: 'com.example.MyAspect com.example.MyAspect.aspectOf()'
    at com.example.MyAspectTest.<init>(MyAspectTest.java:57)

:MyAspect.java

package com.example;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class MyAspect {

    @AfterReturning("""
            @target(com.example.MyAnnotation)
            && (execution(* *.*(..)) || execution(* .new(..)))
            """)
    public void intercept(JoinPoint JoinPoint) throws Throwable {
        System.out.println("********** MyAspect intercepted");
    }
}

There is a subtle error in your aop.xml :

<include within="@com.example.MyAnnotation *" />

The include within rule is too narrow. Aspect weaving is falsely limited to only target classes, the aspect class itself is excluded, because it does not carry the target5 annotation itself. The effect is that the weaver never finishes the aspect itself - remember, it was not compiled by AJC before. This caused NoSuchMethodError: ...MyAspect.aspectOf() . So widening the weaving scope to the whole base package fixes your problem:

<include within="com.example..*" />

Two more things you should improve:

  • Use @within rather than @target , because @target is evaluated dynamically during runtime. Only then we know for certain which exact type a target instance has. @within however can be evaluated statically during weaving.
  • Use AspectJ 1.9.8.RC3 due to use of Java 17 (you seem to like the new text blocks). For LTW, this might not be strictly necessary as long as the byte code is compatible, but latest when trying to compile Java 17 code, AspectJ 1.9.7 would not suffice, because it only supports up to Java 15.

Here is my pull request with the three corresponding commits.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM