I'm trying to weave some aspects at compile time into a project that becomes a WAR. The aspects advise classes that are within the same project (though in different packages).
I get the warning:
Advice not applied
My aspect is not being executed. Here's my setup:
annotation FooAnnotation.java:
package a;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface FooAnnotation {}
aspect FooAdvice.aj:
package a;
public aspect FooAdvice {
private static final Log log = LogFactory.getLog(FooAdvice.class);
Object around() : call( @FooAnnotation * *(..)) {
log.info(String.format("Testing around"));
return proceed();
}
}
I also tried the annotation:
@Around("call( @FooAnnotation * *(..))")
public Object checkFoo( ProceedingJoinPoint joinPoint) throws Throwable {
As far as I can tell, my pointcut specification is correct, but for some reason the ajc compiler isn't playing ball.
Class FooClass.java:
package b;
@ApplicationPath("/service")
@Path("/{param}")
@Produces("application/json")
@Provider
public class FooClass {
@POST
@PUT
@Path("/{context}/{resource}")
@FooAnnotation
public String updateResource(...) {}
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>zzz.group</groupId>
<artifactId>yyy.artifact</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>yyy.name</name>
<properties>
<endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<javaVersion>1.6</javaVersion>
<org.aspectj-version>1.7.2</org.aspectj-version>
</properties>
<dependencies>
<dependency>
... stuff ...
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${org.aspectj-version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.0</version>
<configuration>
<source>${javaVersion}</source>
<target>${javaVersion}</target>
<compilerArguments>
<endorseddirs>${endorsed.dir}</endorseddirs>
</compilerArguments>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<!--
Have to use version 1.2 since version 1.3 does not appear to work
with ITDs
-->
<version>1.4</version>
<dependencies>
<!--
You must use Maven 2.0.9 or above or these are ignored (see
MNG-2972)
-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${org.aspectj-version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>${org.aspectj-version}</version>
</dependency>
</dependencies>
<executions>
<execution>
<goals>
<goal>compile</goal>
<!-- <goal>test-compile</goal> -->
</goals>
</execution>
</executions>
<configuration>
<outxml>true</outxml>
<source>${javaVersion}</source>
<target>${javaVersion}</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
Aha! Found the answer here:
aspectj: why advice cannot be applied?
It has nothing to do with maven.
The reason is that in my example, the method is being called from within the jax-rs framework by indirect loading. The call()
advice wants to weave the caller, but the ajc compiler can't know where the caller is. The fix is to change the advice to execution()
thusly:
Object around() : execution(@FooAnnotation * *(..)) {...}
This differs because it weaves around the execution (which ajc can find), rather than the caller.
Done.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With