Search code examples
aspectjaspectj-maven-plugin

AspectJ annotations are not working in JAVA maven project (Not spring project)


I'm trying to implement AspectJ annotations in JAVA maven project without spring. I have added Aspects and create annotation. But its not invoking the Aspects where i have added as Annotation to the method..Below is my code..Also the project link - https://github.com/chandru-kumar/aop-example

I have added aspectj maven plugin as well..But its not getting invoked..Can you pls help..? Not sure what I'm missing. I haven't found any example without Spring project..

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>com.aop.example</groupId>
  <artifactId>aop-example</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  
    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.6</version>
        </dependency>
        
        <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjtools</artifactId>
            <version>1.9.6</version>
        </dependency>
        
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.9.6</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>aspectj-maven-plugin</artifactId>
                <version>1.11</version>
                <configuration>
                    <complianceLevel>1.8</complianceLevel>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.22.0</version>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <useIncrementalCompilation>false</useIncrementalCompilation>
                </configuration>
            </plugin>
            
            <!-- <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>aspectj-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                        <configuration>
                            <complianceLevel>1.8</complianceLevel>
                            <source>1.8</source>
                            <target>1.8</target>
                        </configuration>
                    </execution>
                </executions>
            </plugin> -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                        <configuration>
                            <archive>
                                <manifest>
                                    <mainClass>
                                        com.aop.example.Test
                                    </mainClass>
                                </manifest>
                            </archive>
                            <descriptorRefs>
                                <descriptorRef>jar-with-dependencies</descriptorRef>
                            </descriptorRefs>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

JAVA - Aspects - Advice

package com.aop.advices;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;

public class SysoutAdvice {
    @Around("@annotation(com.annotations.Sysout)")
    public Object print(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("Start....");
        Object object = proceedingJoinPoint.proceed();
        System.out.println("End....");
        return object;
    }
}

JAVA - Annotation

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

@retention(RUNTIME)
@target(METHOD)
public @interface Sysout{}

Solution

  • I can tell that you are an AspectJ beginner. You made many mistakes. But do not worry, you are going to learn and get more experience over time.

    Annotation must have RUNTIME scope

    Otherwise the compiled code will not have an annotation to intercept, only the source code, which does not help.

    enter image description here

    Aspect must have @Aspect annotation

    Otherwise the AspectJ compiler will not identify the class as an aspect.

    enter image description here

    Avoid double log output

    If you do not add && execution(* *(..)), the aspect will intercept both call and execution joinpoints. The effect would be double log messages, because the aspect advice is triggered twice.

    enter image description here

    Add missing Maven plugin execution

    Otherwise the AspectJ Maven plugin does not compile anything, because you did not tell it what to do.

    enter image description here

    Delete redundant AspectJ dependencies

    Otherwise the Assembly plugin will pack them into the executable JAR, blowing it up to size 13.4 MB. But actually, you only need the AspectJ runtime aspectjrt in order to run an application when using compile-time weaving. The other two are for load-time weaving (aspectjweaver) and for the AspectJ compiler (aspetjtools), both of which you do not need during runtime.

    If you follow my advice to remove those two, the JAR size shrinks dramatically to 0.12 MB. That is more than a factor 100 smaller.

    enter image description here

    Make sure the old AspectJ Maven plugin uses an up-to-date AspectJ compiler

    The version number should be the same as the one used for aspectjrt. So you do not need aspetjtools as a runtime dependency, but as a plugin dependency, if you want to make sure you have identical versions.

    enter image description here

    This step is optional, but AspectJ Maven 1.11 uses AspectJ Tools 1.8.13 by default. This is fine if you just compile Java 8 code, because AspectJ Maven 1.11 does not support more than Java 8.

    If you want a more modern plugin supporting AspectJ 1.9.7.M3 and Java 16, please look at the dev.aspectj plugin version (please note the other Maven group ID!).

    There are other suboptimal things that should be changed in your Maven configuration, but this is the most important stuff, which makes your project run and your executable JAR small.


    Update: Here is my pull request which fixes the problems above and a few more (see commit comments).