0

I'm trying to get my Aspect class to work but it gets completely ignored.

I have following files:

MyAnnotation.java

package annotations;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAnnotation {
}

MyAspect.java

package annotations;

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

@Aspect
public class MyAspect {

    @Before("@annotation(annotations.MyAnnotation)*")
    public void interceptMethods(final JoinPoint thisJoinPoint) {
        System.out.println(thisJoinPoint);
    }
}

MyClass.java

package annotations;

import org.springframework.stereotype.Service;

@Service
public class MyClass {

    @MyAnnotation
    public int myMethod(final int i) {
        System.out.println("method: " + i);
        return i;
    }
}

MyRestController.java

package annotations;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyRestController {

    @Autowired
    MyClass myClass;

    @GetMapping("/myClass")
    private int callMyMethod() {
        return myClass.myMethod(1);
    }
}

Application.java

package annotations;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>experiments</groupId>
    <artifactId>annotations</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
            <version>2.2.11.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.2.11.RELEASE</version>
        </dependency>
    </dependencies>
</project>

Does anyone see the problem and how to fix it?

I've tried multiple Before expressions ("execution(* annotations..(..))") but I just can't see to get it working.

I've tried Around instead of Before.

I've tried Pointcuts with Before.

I've been through articles: AspectJ @Before annotation issue Spring AspectJ, pointcut before method execution where method OR class is annotated

FER_Viborg
  • 57
  • 1
  • 9
  • Do you have the the `org.aspectj:aspectjweaver` dependency on the class path at runtime? – krankkk Dec 03 '22 at 15:59
  • @krankkk, Yes, the spring-boot-starter-aop has that dependency. Just to be sure, I've now added: ` org.aspectj aspectjweaver 1.9.9.1 runtime ` and then I got the "The import org.aspectj cannot be resolved" errors so I also had to add: ` org.aspectj aspectjrt 1.9.4 ` It still doesn't work... – FER_Viborg Dec 03 '22 at 16:12
  • Have you look at [this SO Anser](https://stackoverflow.com/a/47062752/15219976)? – krankkk Dec 03 '22 at 16:23
  • Second link is not a spring boot answer ... :| I've taken a look, but it is far from perfect example and I don't understand what is going on or how to fix my code. What do you think that could be missing now that my application definitely has an aspectjweaver in runtime? – FER_Viborg Dec 03 '22 at 23:46
  • I've moved one step forward. I needed to add `@Component` to `MyAspect` class. Now I'm getting null pointer exception: `java.lang.NullPointerException: null at annotations.MyRestController.callMyMethod(MyRestController.java:15) ~[classes/:na]` – FER_Viborg Dec 04 '22 at 00:20

1 Answers1

1

I finally did it. I'll leave the solution here for other people in need for a basic example.

These are the files:

MyAnnotation.java

package annotations;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAnnotation {
}

MyAspect.java - it's tricky because:

  1. annotation @Aspect is not sufficient. The annotation @Component also needs to be added to aspect class. If annotation @Component is omitted, the application will ignore the class.
  2. in @Before annotation, there needs to be "and args(*)". If the args are omitted, there will be null pointer exception.

Code:

package annotations;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class MyAspect {
    @Before("execution(* annotations.*.*(..)) and args(*)")
    public void beforeExecution(final JoinPoint joinPoint) {
        System.out.println("5");
    }
}

MyClass.java

package annotations;

import org.springframework.stereotype.Service;

@Service
public class MyClass {

    @MyAnnotation
    public int myMethod(final int i) {
        System.out.println("method: " + i);
        return i;
    }
}

MyRestController

package annotations;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyRestController {

    @Autowired
    MyClass myClass;

    @GetMapping("/myClass")
    private int callMyMethod() {
        return myClass.myMethod(1);
    }
}

Application.java

package annotations;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

    public static void main(final String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>experiments</groupId>
<artifactId>annotations</artifactId>
<version>0.0.1-SNAPSHOT</version>

<properties>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-aop</artifactId>
        <version>2.2.11.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>2.2.11.RELEASE</version>
    </dependency>
</dependencies>
FER_Viborg
  • 57
  • 1
  • 9