javaspring-bootaspectjload-time-weaving

Spring Boot 3 + Aspectj with Load Time Weaving = java.lang.NoSuchMethodError: aspectOf()


I'm trying to configure AspectJ LTW (Load-Time Weaving) in my Spring Boot library. The goal is to intercept the execution of every method in the classpath (including non-Spring beans) to monitor execution time. During test execution, I'm encountering the following error: java.lang.NoSuchMethodError: 'LoadTimeWeavingAspect.aspectOf()'.

My configuration class:

@Configuration
@EnableLoadTimeWeaving(aspectjWeaving = EnableLoadTimeWeaving.AspectJWeaving.ENABLED)
public class AspectJWeaverConfiguration {}

My META-INF/aop.xml file:

<aspectj>
    <aspects>
        <aspect name="project.base.package.performance_monitor.LoadTimeWeavingAspect"/>
    </aspects>
    <weaver options="-verbose -showWeaveInfo">
        <include within="project.base.package..*"/>
    </weaver>
</aspectj>

My Aspect class:

@Aspect
public class LoadTimeWeavingAspect {

    @Around("within(project.base.package..*)")
    public Object around(final ProceedingJoinPoint pjp) throws Throwable {
        Method method = ((MethodSignature) pjp.getSignature()).getMethod();
        PerformanceWatcher.start(method.getDeclaringClass().getName() + "." + method.getName());
        try {
            return pjp.proceed();
        } finally {
            PerformanceWatcher.stop();
        }
    }

}

My pom.xml file:

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-instrument</artifactId>
            <version>${spring-instrument.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>io.micrometer</groupId>
            <artifactId>micrometer-tracing-bridge-otel</artifactId>
            <version>${micrometer-tracing.version}</version>
        </dependency>
</dependencies>

I'm passing the following java agent when executing the tests: -javaagent:"C:\Users\user\.m2\repository\org\springframework\spring-instrument\6.2.8\spring-instrument-6.2.8.jar"

Any idea how to do it the right way? It's been a challenge to find documentation to guide me.

I'm following this two publications to guide me:


Solution

  • You need to weave the aspects before the aspectOf method is being added. You can do this through 1 of 2 means.

    1. Add the aspject maven compiler to your pom.xml
    2. Include the aspectjweaver as an additional Java agent

    Add the compiler

    <build>
      <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>aspectj-maven-plugin</artifactId>
                <version>1.15.0</version>
                <configuration>
                    <showWeaveInfo>true</showWeaveInfo>
                    <release>${java.version}</source>
                    <Xlint>ignore</Xlint>
                    <encoding>UTF-8</encoding>
                    <verbose>true</verbose>
                </configuration>
                <executions>
                    <execution>
                        <!-- IMPORTANT -->
                        <phase>process-sources</phase>
                        <goals>
                            <goal>compile</goal>
                            <goal>test-compile</goal>
                        </goals>
                    </execution>
                </executions>
                <dependencies>
                    <dependency>
                        <groupId>org.aspectj</groupId>
                        <artifactId>aspectjtools</artifactId>
                        <version>${aspectj.version}</version>
                    </dependency>
                </dependencies>
            </plugin>  
      </plugins>
    </build>
    

    Something along these lines.

    Add the javaagent

    Or you can add an additional java agent for AspectJ.

    -javaagent:/path/to/aspectjweaver.jar
    -javaagent:"C:\Users\user\.m2\repository\org\springframework\spring-instrument\6.2.8\spring-instrument-6.2.8.jar"
    

    See also Compiling with maven-compiler-plugin and aspectj-maven-plugin for a more detailed explanation and links to other answers with more indepth answers.