I wanted to use AOP-styled annotations for @Around
advice in a non-Spring project. I was able to make up some code, but it's been giving me trouble - instead of seeing the console output as coded in the Advice
I can only see the SampleClass
method's printout.
Providing a minimal, reproductible example of my code. Hoping to get some hint on how to get it working. Thanks!
Main.java
package pl.bart;
public class Main {
public static void main(String[] args) {
System.out.println(new SampleClass().a());
}
}
SampleClass.java
package pl.bart;
public class SampleClass {
@Annotation
public String a() {
return "Hello from sample class";
}
}
Annotation.java
package pl.bart;
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 Annotation {
}
Advice.java
package pl.bart;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public class Advice {
@Pointcut("@annotation(Annotation)")
public void callAt() {
}
@Around("callAt()")
public Object advice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("Hello from advice");
return proceedingJoinPoint.proceed(proceedingJoinPoint.getArgs());
}
}
META-INF/aop.xml
<aspectj>
<aspects>
<aspect name="pl.bart.Advice"/>
<weaver options="-verbose -showWeaveInfo">
<include within="pl.bart.*"/>
</weaver>
</aspects>
</aspectj>
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>pl.bart</groupId>
<artifactId>aspectj-test</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.5.4</version>
</dependency>
<dependency>
<groupId>aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.5.4</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<configuration>
<argLine>
-javaagent:"${settings.localRepository}"/org/aspectj/
aspectjweaver/1.8.9/
aspectjweaver-1.8.9.jar
</argLine>
<useSystemClassLoader>true</useSystemClassLoader>
<forkMode>always</forkMode>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.14.0</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
CodePudding user response:
The are three mistakes in you project.
1.
@Pointcut("@annotation(Annotation)")
public void callAt() {
}
use fully qualified names of classes, i.e. pl.bart.Annotation
instead of Annotation
- it costs you nothing but saves a lot of time, in particular aspectj 1.5.4 "does not support" simple names.
2.
<dependency>
<groupId>aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.5.4</version>
</dependency>
<dependency>
<groupId>aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.5.4</version>
</dependency>
aspectj does some magic with bytecode, and it is too naive to expect the library released 12 years ago supports java 17, switch to the recent aspectj 1.9.9, also note you need to add --add-opens java.base/java.lang=ALL-UNNAMED
to JVM arguments.
3.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.14.0</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
</plugin>
if you are going to use load time weaving
and you don't use native aspectJ (.aj) syntax
, you do not need aspectj-maven-plugin
- it compiles .aj
files and performs compile time weaving
.