Search code examples
javaaopaspectjaspectaspectj-maven-plugin

Project not compiling properly with AspectJ Maven


I am trying to work with AspectJ in IntelliJ Community Edition.

It's not working as expected. Where do am I making a mistake? Any help/insights would be very much appreciated.

Technology Ref:

  1. IntelliJ IDEA 2018.2.4 (Community Edition)
  2. java version "1.8.0_77"
package org.kayd;
    
public class Client {
  public static void main(String[] args) {
    Client data = new Client();
    data.data();
  }

  public void data() {
    System.out.println("kayd");
  }
}

Aspect Class

package org.kayd;

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

@Aspect
public class AspectTest {
  @Pointcut("execution(* *(..))")
  public void defineEntryPoint() {}

  @Before("defineEntryPoint()")
  public void log(JoinPoint joinPoint) {
    System.out.println("log");
  }

  @After("execution(org.kayd.Client.data())")
  public void after() {
    System.out.println("log");
  }
}

AOP.xml

<aspectj>
  <aspects>
    <aspect name="org.kayd.AspectTest"/>
  </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>org.kayd</groupId>
  <artifactId>AOP</artifactId>
  <version>1.0-SNAPSHOT</version>

  <dependencies>
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-api</artifactId>
      <version>5.3.2</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjrt</artifactId>
      <version>1.9.2</version>
    </dependency>
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>1.9.2</version>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>aspectj-maven-plugin</artifactId>
        <version>1.9</version>
        <configuration>
          <showWeaveInfo>true</showWeaveInfo>
          <source>1.8</source>
          <target>1.8</target>
          <Xlint>ignore</Xlint>
          <complianceLevel>${java.version}</complianceLevel>
          <encoding>UTF-8</encoding>
          <verbose>true</verbose>
        </configuration>
        <executions>
          <execution>
            <phase>process-sources</phase>
            <goals>
              <goal>compile</goal>
              <goal>test-compile</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

Screenshot

Project Structure

Ref: I already looked into these questions but still not working.


Solution

  • I just had a little bit of time and recreated your Maven project on my machine. What I said in my comment is actually true, so I am quoting myself here in order to turn it into an answer:

    At first glance two things strike me as odd:

    • You apply compile-time weaving, but also provide an aop.xml which is only needed for load-time weaving. So which way do you want to go? For CTW you can just remove it.
    • Secondly, the pointcut execution(org.kayd.Client.data()) should yield a compile error because the syntax is invalid (no return type specified for the method signature). You should rather use something like execution(* org.kayd.Client.data()) or execution(void org.kayd.Client.data()).

    I want to add that using after as a method name is not advised because in AspectJ native syntax it is a reserved keyword. The compiler does not complain, but still you should be careful here.

    I modified your aspect like this to avoid the Maven compile error and also to see some more information on the console:

    package org.kayd;
    
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.annotation.After;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.annotation.Pointcut;
    
    @Aspect
    public class AspectTest {
      @Pointcut("execution(* *(..))")
      public void defineEntryPoint() {}
    
      @Before("defineEntryPoint()")
      public void log(JoinPoint joinPoint) {
        System.out.println("Before advice on " + joinPoint);
      }
    
      @After("execution(org.kayd.Client.data())")
      public void afterAdvice(JoinPoint joinPoint) {
        System.out.println("After advice on " + joinPoint);
      }
    }
    

    I also pimped your POM a bit because you use the latest AspectJ version on one hand, but an old version of AspectJ Maven plugin depending on an older version, which leads to strange log output on the Maven console. Furthermore, I added a One-JAR packager and Maven Exec plugin, so you have your whole application in one Über-JAR and can just run it without anything else on the classpath.

    <?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>org.kayd</groupId>
      <artifactId>AOP</artifactId>
      <version>1.0-SNAPSHOT</version>
    
      <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.source-target.version>1.8</java.source-target.version>
        <aspectj.version>1.9.2</aspectj.version>
        <main-class>org.kayd.Client</main-class>
      </properties>
    
      <build>
    
        <pluginManagement>
          <plugins>
            <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-compiler-plugin</artifactId>
              <version>3.3</version>
              <configuration>
                <source>${java.source-target.version}</source>
                <target>${java.source-target.version}</target>
                <!-- IMPORTANT -->
                <useIncrementalCompilation>false</useIncrementalCompilation>
              </configuration>
            </plugin>
            <plugin>
              <groupId>org.codehaus.mojo</groupId>
              <artifactId>aspectj-maven-plugin</artifactId>
              <version>1.11</version>
              <configuration>
                <!--<showWeaveInfo>true</showWeaveInfo>-->
                <source>${java.source-target.version}</source>
                <target>${java.source-target.version}</target>
                <Xlint>ignore</Xlint>
                <complianceLevel>${java.source-target.version}</complianceLevel>
                <encoding>${project.build.sourceEncoding}</encoding>
                <!--<verbose>true</verbose>-->
                <!--<warn>constructorName,packageDefaultMethod,deprecation,maskedCatchBlocks,unusedLocals,unusedArguments,unusedImport</warn>-->
              </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>
                <dependency>
                  <groupId>org.aspectj</groupId>
                  <artifactId>aspectjweaver</artifactId>
                  <version>${aspectj.version}</version>
                </dependency>
              </dependencies>
            </plugin>
            <plugin>
              <groupId>org.codehaus.mojo</groupId>
              <artifactId>exec-maven-plugin</artifactId>
              <version>1.4.0</version>
              <configuration>
                <mainClass>${main-class}</mainClass>
              </configuration>
            </plugin>
            <plugin>
              <groupId>com.jolira</groupId>
              <artifactId>onejar-maven-plugin</artifactId>
              <version>1.4.4</version>
              <executions>
                <execution>
                  <goals>
                    <goal>one-jar</goal>
                  </goals>
                </execution>
              </executions>
              <configuration>
                <onejarVersion>0.96</onejarVersion>
                <mainClass>de.scrum_master.app.FooBar</mainClass>
                <attachToBuild>true</attachToBuild>
              </configuration>
            </plugin>
          </plugins>
        </pluginManagement>
    
        <plugins>
          <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>aspectj-maven-plugin</artifactId>
          </plugin>
          <plugin>
            <groupId>com.jolira</groupId>
            <artifactId>onejar-maven-plugin</artifactId>
            <configuration>
              <mainClass>${main-class}</mainClass>
            </configuration>
          </plugin>
          <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>exec-maven-plugin</artifactId>
          </plugin>
        </plugins>
    
      </build>
    
      <dependencies>
        <dependency>
          <groupId>org.aspectj</groupId>
          <artifactId>aspectjrt</artifactId>
          <version>${aspectj.version}</version>
        </dependency>
      </dependencies>
    
    </project>
    

    Then do something like mvn clean verify and afterwards either of those two:

    $ mvn exec:java
    
    [INFO] Scanning for projects...
    [INFO]
    [INFO] ----------------------------< org.kayd:AOP >----------------------------
    [INFO] Building AOP 1.0-SNAPSHOT
    [INFO] --------------------------------[ jar ]---------------------------------
    [INFO]
    [INFO] --- exec-maven-plugin:1.4.0:java (default-cli) @ AOP ---
    Before advice on execution(void org.kayd.Client.main(String[]))
    Before advice on execution(void org.kayd.Client.data())
    kayd
    After advice on execution(void org.kayd.Client.data())
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESS
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time: 1.043 s
    [INFO] Finished at: 2018-12-12T12:07:59+07:00
    [INFO] ------------------------------------------------------------------------
    

    Or if you want to run the Über-JAR:

    $ java -jar target\AOP-1.0-SNAPSHOT.one-jar.jar
    
    Before advice on execution(void org.kayd.Client.main(String[]))
    Before advice on execution(void org.kayd.Client.data())
    kayd
    After advice on execution(void org.kayd.Client.data())