javaspring-bootaopaspectjspring-aspects

Spring Boot Upgrade from 3.2.x to 3.3.x Causing NoSuchMethodException in AspectJ


I have a legacy application that started as a core Java project, later incorporated Spring, and was eventually converted to a Spring Boot application. We are currently running on Spring Boot 3.2.12, and I am in the process of upgrading it to 3.3.5. However, after this upgrade, my application fails to start with the following exception:

Error creating bean with name 'logAspect' defined in class path resource 
[com/generalnitin/springaop/config/AspectConfig.class]: Failed to instantiate 
[com.generalnitin.springaop.aspects.LogAspect]: Factory method 'logAspect' threw 
exception with message: Exception while initializing 
com.generalnitin.springaop.aspects.LogAspect: java.lang.NoSuchMethodException: 
com.generalnitin.springaop.aspects.LogAspect.aspectOf()

Running a simple command mvn clean install results in the default SpringBootTest failing with version 3.3.5, whereas it works perfectly fine with version 3.2.12.

I have created a dummy project where I am able to reproduce this issue. You can find the project on GitHub here: https://github.com/GeneralNitin/Spring-Aspect

In the pom.xml, if you comment and uncomment the versions as shown below, you can reproduce the issue:

<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<!-- <version>3.2.12</version> -->
<version>3.3.5</version>

The surprising part is that the aspectj.version is the same in both Spring Boot 3.2.12 and 3.3.5:

<aspectj.version>1.9.22.1</aspectj.version>

I am unable to figure out what the issue is. Any help or pointers to resolve this would be greatly appreciated.


Solution

  • I refactored and cleaned up your project a bit on the main branch of my fork before branching off two solutions:

    Spring AOP solution

    See PR #1.

    Get rid of jcabi weaving plugin and make aspect a Spring @Component.

    We also do not need @Configuration class AspectConfig, if we do not use any special Spring AOP settings. It will just work like this.

    The console log running the test should contain something like this:

    service 0.0839
    Hello World!
    

    AspectJ solution

    See PR #2.

    Use AspectJ Maven instead of jcabi weaving plugin for binary weaving.

    AJ Maven is the recommended plugin for such things, not an exotic plugin providing no added value here.

    We also do not need @Configuration class AspectConfig, because a native AspectJ aspect is not a Spring-managed component.

    The console log running the test should contain something like this:

    service 0.0839
    Hello World!
    

    Injecting other Spring components into the aspect

    In your MCVe, there is no need to do that, but maybe in your real project there is. So, I want to explain how to do it:

    In the Spring AOP solution, the aspect itself is already a Spring component. So, you can simply use @Autowired like for any other component or bean, such as controllers or services.

    In the native AspectJ solution, you would use the spring-aspects dependency with a combination of @Configurable on the native AspectJ aspect and @EnableSpringConfigured on a @Configuration class. See my answer here for an example.