简体   繁体   中英

AspectJ & Maven warning: “Advice defined in … has not been applied?”

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM