Skip to content
Advertisement

Implementation of AspectJ example not working

I’m try to implement a simple AspectJ annotation example from https://www.baeldung.com/aspectj. The difference is, that I want to use the annotation at a JUnit TestClass. I googled a while for the solution but don’t find the right hint.

Part of my pom.xml

<dependencies>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.9.7</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjrt</artifactId>
        <version>1.9.7</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>aspectj-maven-plugin</artifactId>
        <version>1.14.0</version>
    </dependency>
</dependencies>

<plugins>
    <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>aspectj-maven-plugin</artifactId>
        <version>1.14.0</version>
        <configuration>
            <complianceLevel>1.8</complianceLevel>
            <!--<source>1.8</source>
            <target>1.8</target>-->
            <showWeaveInfo>true</showWeaveInfo>
            <verbose>true</verbose>
            <Xlint>ignore</Xlint>
            <!--<encoding>UTF-8 </encoding>-->
        </configuration>
        <executions>
            <execution>
                <phase>process-sources</phase>
                <goals>
                    <!-- use this goal to weave all your main classes -->
                    <goal>compile</goal>
                    <!-- use this goal to weave all your test classes -->
                    <goal>test-compile</goal>
                </goals>
            </execution>
        </executions>
    </plugin>       
</plugins>

My Annotation:

package com.mb.mtpp.main.extension.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, ElementType.TYPE, ElementType.FIELD})
public @interface Secured {
public boolean isLocked() default false;
}

My Aspect:

package com.mb.mtpp.main.extension.aspectj;

import com.mb.mtpp.main.extension.annotations.Secured;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public final class SecuredMethodAspect {

@Pointcut("@annotation(secured)")
    public void callAt(Secured secured) {
}

@Before("callAt(secured)")
public void around(JoinPoint pjp, Secured secured) throws Throwable {
    System.out.println("++++++++test++++++++");
    //return secured.isLocked() ? null : pjp.proceed();
}
}
@Secured(isLocked = true)
public class DummyClassTest {

@Test
@Secured(isLocked = true)
public void dummyTest4(){
    log.info("Test 4");
}
}

The Advice is mentions to the class annotation, I see it in the logs:

CLASSPATH component C:Program FilesJetBrainsIntelliJ IDEA Community Edition 2021.3.2pluginsmavenlibmaven3bootplexus-classworlds.license: java.util.zip.ZipException: error in opening zip file
[INFO] Join point 'staticinitialization(void com.mb.mtpp.main.dummy.DummyClassTest.<clinit>())' in Type 'com.mb.mtpp.main.dummy.DummyClassTest' (DummyClassTest.java:23) advised by before advice from 'com.mb.mtpp.main.extension.aspectj.SecuredMethodAspect' (SecuredMethodAspect.java:62)
[INFO] Join point 'method-execution(void com.mb.mtpp.main.dummy.DummyClassTest.dummyTest3())' in Type 'com.mb.mtpp.main.dummy.DummyClassTest' (DummyClassTest.java:64) advised by before advice from 'com.mb.mtpp.main.extension.aspectj.SecuredMethodAspect' (SecuredMethodAspect.java:62)
[INFO] Join point 'method-execution(void com.mb.mtpp.main.dummy.DummyClassTest.dummyTest4())' in Type 'com.mb.mtpp.main.dummy.DummyClassTest' (DummyClassTest.java:71) advised by before advice from 'com.mb.mtpp.main.extension.aspectj.SecuredMethodAspect' (SecuredMethodAspect.java:62)
[INFO] Join point 'method-call(void com.mb.mtpp.main.extension.DummyClass.function1())' in Type 'com.mb.mtpp.main.dummy.DummyClassTest' (DummyClassTest.java:79) advised by before advice from 'com.mb.mtpp.main.extension.aspectj.SecuredMethodAspect' (SecuredMethodAspect.java:62)
[INFO] Join point 'method-call(void com.mb.mtpp.main.extension.DummyClass.function2())' in Type 'com.mb.mtpp.main.dummy.DummyClassTest' (DummyClassTest.java:80) advised by before advice from 'com.mb.mtpp.main.extension.aspectj.SecuredMethodAspect' (SecuredMethodAspect.java:62)
[INFO] Join point 'method-execution(void com.mb.mtpp.main.extension.DummyClass.function1())' in Type 'com.mb.mtpp.main.extension.DummyClass' (DummyClass.java:8) advised by before advice from 'com.mb.mtpp.main.extension.aspectj.SecuredMethodAspect' (SecuredMethodAspect.java:62)
[INFO] Join point 'method-execution(void com.mb.mtpp.main.extension.DummyClass.function2())' in Type 'com.mb.mtpp.main.extension.DummyClass' (DummyClass.java:13) advised by before advice from 'com.mb.mtpp.main.extension.aspectj.SecuredMethodAspect' (SecuredMethodAspect.java:62)

But the log “++++++++test++++++++” is not shown in the console. It executes as the advice is not there. I annotated the class, the testcase and a method as in the example. I tried different settings for my Pointcut but the shown is the best. Then the class is also advised. I don’t know what’s wrong.

Advertisement

Answer

Sorry, I was busy. Assuming that your directory layout is like this:

Maven directory layout

Some sample classes might look like this:

package com.mb.mtpp.main.extension.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, ElementType.TYPE, ElementType.FIELD })
public @interface Secured {
  boolean isLocked() default false;
}
package com.mb.mtpp.main.extension;

import com.mb.mtpp.main.extension.annotations.Secured;

public class MyClass {
  @Secured
  public void doSomething() {}
}
package com.mb.mtpp.main.extension.aspectj;

import com.mb.mtpp.main.extension.annotations.Secured;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public final class SecuredMethodAspect {
  @Pointcut("@annotation(secured) && execution(* *(..))")
  public void securedMethods(Secured secured) {}

  @Before("securedMethods(secured)")
  public void interceptSecuredMethods(JoinPoint joinPoint, Secured secured) {
    System.out.println(joinPoint);
  }
}
package com.mb.mtpp.main.extension;

import com.mb.mtpp.main.extension.annotations.Secured;
import org.junit.jupiter.api.Test;

@Secured(isLocked = true)
public class MyTest {
  @Test
  @Secured(isLocked = true)
  public void dummyTest4(){
    System.out.println("Test 4");
  }

  @Test
  @Secured(isLocked = true)
  public void dummyTest5(){
    System.out.println("Test 5");
    new MyClass().doSomething();
  }
}

Your POM would be:

<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.example</groupId>
  <artifactId>SO_AJ_AspectNotTriggered_72344739</artifactId>
  <version>1.0-SNAPSHOT</version>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjrt</artifactId>
      <version>1.9.7</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-engine</artifactId>
      <version>5.8.2</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>3.0.0-M6</version>
      </plugin>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>aspectj-maven-plugin</artifactId>
        <version>1.14.0</version>
        <configuration>
          <complianceLevel>1.8</complianceLevel>
          <showWeaveInfo>true</showWeaveInfo>
          <verbose>true</verbose>
          <Xlint>ignore</Xlint>
          <encoding>UTF-8</encoding>
        </configuration>
        <executions>
          <execution>
            <goals>
              <!--<goal>compile</goal>-->
              <goal>test-compile</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

</project>

Then if you either run mvn clean test or simply import the project into IntelliJ IDEA, the log output will be:

execution(void com.mb.mtpp.main.extension.MyTest.dummyTest4())
Test 4
execution(void com.mb.mtpp.main.extension.MyTest.dummyTest5())
Test 5

Now if for whatever reason you also want to apply the aspect to the annotated application class, simply

  • move the aspect from src/test/java to src/main/java,
  • remove <scope>test</scope> from aspectjrt and
  • uncomment <goal>compile</goal>.

Then the console log would be:

execution(void com.mb.mtpp.main.extension.MyTest.dummyTest4())
Test 4
execution(void com.mb.mtpp.main.extension.MyTest.dummyTest5())
Test 5
execution(void com.mb.mtpp.main.extension.MyClass.doSomething())

See? Application class MyClass also gets intercepted in this case.


Update: Concerning why it was not working in your own example, that was because your POM was configured in such a way that Maven Compiler Plugin recompiled your classes after the aspects had been woven my AspectJ Maven Plugin. The result was that the aspect information was lost due to overwritten class files.

Advertisement