javamavenaspectjaspectj-maven-plugincompile-time-weaving

Using AspectJ annotations in maven project: weaving is not working


I am trying to use AspectJ in a simple project without using Spring, and while I have seen similar questions and my code seems to be correct, I don't understand why it's not working. I'm using Eclipse Oxygen 4.7.3 (not using AJDT tools), JDK 7, maven 3.5.2, and my code is as follows:

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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com</groupId>
  <artifactId>aspect-tutorial</artifactId>
  <version>0.0.1-SNAPSHOT</version>


<properties>
    <maven.compiler.plugin.version>3.5.1</maven.compiler.plugin.version>
</properties>

<dependencies>

    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjrt</artifactId>
        <version>1.8.7</version>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.8.8</version>
    </dependency>
</dependencies>


<build>
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>aspectj-maven-plugin</artifactId>
            <version>1.8</version>
            <configuration>
                <complianceLevel>1.7</complianceLevel>
                <source>1.7</source>
                <target>1.7</target>
            </configuration>

        </plugin>
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>${maven.compiler.plugin.version}</version>
            <configuration>
                <source>1.7</source>
                <target>1.7</target>
            </configuration>
        </plugin>

    </plugins>
</build>
</project>

MainApp.java

package com.pkg;

public class MainApp {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        HelloWorld a = new HelloWorld();
        a.printHello();
    }
}

HelloWorld.java

package com.pkg;

public class HelloWorld {
    private String name;

    public void setName(String name) {
        this.name = name;
    }

    public void printHello() {
        System.out.println("Print Hello...");
   }

}

TestAspect.java

package com.pkg;

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


@Aspect
public class TestAspect {       

    @Before("execution(* com.pkg.HelloWorld.printHello(..))")
    public void testBefore2(){
        System.out.println("Yeeha");
    }


}

Running mvn clean install is successful, but the output only prints the "Print Hello..." part. Should I use a different approach? (Maybe use a .aj file instead, or try load-time-weaving) Any help appreciated.


Solution

  • The problem is the configuration of both AspectJ Maven and Maven Compiler. My POMs for AspectJ usually look a bit different than yours (a few more settings), but here is yours with minimal changes in order to make it work:

    <?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>com</groupId>
      <artifactId>aspect-tutorial</artifactId>
      <version>0.0.1-SNAPSHOT</version>
    
      <properties>
        <maven.compiler.plugin.version>3.5.1</maven.compiler.plugin.version>
      </properties>
    
      <dependencies>
        <dependency>
          <groupId>org.aspectj</groupId>
          <artifactId>aspectjrt</artifactId>
          <version>1.8.13</version>
        </dependency>
      </dependencies>
    
      <build>
        <plugins>
    
          <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>aspectj-maven-plugin</artifactId>
            <version>1.11</version>
            <configuration>
              <complianceLevel>1.7</complianceLevel>
              <source>1.7</source>
              <target>1.7</target>
            </configuration>
            <executions>
              <execution>
                <!-- IMPORTANT -->
                <phase>process-sources</phase>
                <goals>
                  <goal>compile</goal>
                  <goal>test-compile</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
    
          <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>${maven.compiler.plugin.version}</version>
            <configuration>
              <source>1.7</source>
              <target>1.7</target>
              <!-- IMPORTANT -->
              <useIncrementalCompilation>false</useIncrementalCompilation>
            </configuration>
          </plugin>
    
          <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>exec-maven-plugin</artifactId>
            <version>1.4.0</version>
            <configuration>
              <mainClass>com.pkg.MainApp</mainClass>
            </configuration>
          </plugin>
    
        </plugins>
      </build>
    </project>
    

    See how I set incremental compilation to false for Maven compiler? This is due to an old bug (still unfixed) which actually inverts the switch, so in order to make incremental compilation work you have to "deactivate" it. Very weird.

    You also need to define executions for the process-sources phase for AspectJ Maven.

    Besides, I upgraded to AspectJ Maven 1.11 and thus also to AspectJ runtime 1.8.13.

    I also added Maven Exec plugin in order to easily prove that it is working now. Just call mvn clean compile exec:java and check the output:

    (...)
    [INFO] --- aspectj-maven-plugin:1.11:compile (default) @ aspect-tutorial ---
    [INFO] Showing AJC message detail for messages of types: [error, warning, fail]
    [INFO] 
    [INFO] --- maven-compiler-plugin:3.5.1:compile (default-compile) @ aspect-tutorial ---
    [INFO] Nothing to compile - all classes are up to date
    (...)
    [INFO] --- exec-maven-plugin:1.4.0:java (default-cli) @ aspect-tutorial ---
    Yeeha
    Print Hello...
    (...)
    

    Otherwise I support what Nándor said: Make sure you use AspectJ plugins for Eclipse or IDEA if you also want to run your aspect-enhanced Java code from an IDE.