Search code examples
javaaopaspectjpointcut

Aspectj: Pointcut no longer works when declared in aop.xml ( LTW)


I m trying to define my aspect as a concrete-aspect to be able to define pointcuts in aop.xml without compiling the code. I m using LTW.

when I define my poincut exp in the aspect class itself and define the aspect as a simple aspect ( ), it works fine. however, when I declare the aspect as a concrete-aspect and define the pointcut in aop.xml. the aspect is not working anymore... and it doesn't hit the breakpoint inside my advise anymore...

Here is the code with / without concrete-aspects:

Without concrete aspects ( WORKS FINE):

public abstract aspect AbstractAspect {
    protected abstract pointcut publicMethod();
}

public aspect MethodExecutionTimeAspect extends AbstractAspect {
    public pointcut publicMethod() : execution(public * com.proj.package..*());
    Object around() : publicMethod() {
        .....
        Object ret = proceed();
        ....
   }
}

and the aop.xml

<aspectj>
    <aspects>
    <aspect  name="com.proj.packae.aspectj.MethodExecutionTimeAspect"/> 
    </aspects>
    <weaver options="-verbose">
    </weaver>
</aspectj>

With Concrete aspects ( DOESN'T WORK)

public abstract aspect AbstractAspect {
    protected abstract pointcut publicMethod();
}

public aspect MethodExecutionTimeAspect extends AbstractAspect {
    public pointcut publicMethod() : execution(public * com.proj.package..*());
    Object around() : publicMethod() {
        .....
        Object ret = proceed();
        ....
   }
} 

aop.xml

  <aspectj>
<aspects>

     <concrete-aspect name="com.proj.package.MethodExecutionTimeAspect" extends="com.project.package.aspectj.AbstractAspect">
        <pointcut name="publicMethod" expression="execution(public * com.proj.package..*())" />
    </concrete-aspect>

</aspects>

<weaver options="-verbose">

</weaver>

I m using aspectj 1.6 jars.

When I don't use concret-aspects, this the following logs

[WebappClassLoader@7f62cbb2] info register aspect com.project.package.aspectj.MethodExecutionTimeAspect

and when I use concrete-aspects, I see the following logs:

[WebappClassLoader@393e11ac] info define aspect com.project.package.aspectj.MethodExecutionTimeAspect

No errors are shown on the log, it just look like the concret aspects is not registered.

Please advise.


Solution

  • You made several errors:

    • When using <concrete-aspect>, the concrete pointcut should just be in your aop.xml, not in your code. Maybe it was a copy & paste error, but in your example it looks as if the concrete pointcut was defined twice: in code and in XML.
    • When concretising an abstract aspect, the abstract aspect must already contain the advice you want to map to the concrete pointcut. It cannot be overridden via XML or via a combination of code and XML.

    Look at my own example, quite similar to yours:

    Sample application:

    package de.scrum_master.app;
    
    public class Application {
        public static void main(String[] args) {
            Application app = new Application();
            app.say("Hello world!");
            app.add(11, 22);
        }
    
        private int add(int i, int j) { return i + j; }
        public void say(String message) { System.out.println(message); }
    }
    

    As you can see, there are two public methods (one static, one non-static) and a private method. I did this so as to test if the concrete pointcut later really only catches the public ones.

    Abstract aspect:

    package de.scrum_master.aspectj;
    
    public abstract aspect AbstractAspect {
        protected abstract pointcut publicMethod();
    
        Object around() : publicMethod() {
            System.out.println(thisJoinPointStaticPart);
            return proceed();
        }
    }
    

    aop.xml:

    <?xml version="1.0" encoding="UTF-8"?>
    <aspectj>
        <aspects>
            <concrete-aspect
                name="de.scrum_master.aspectj.ConcreteAspect"
                extends="de.scrum_master.aspectj.AbstractAspect"
            >
                <pointcut
                    name="publicMethod"
                    expression="execution(public * de.scrum_master..*(..))"
                />
            </concrete-aspect>
        </aspects>
    </aspectj>
    

    Application output when using LTW:

    execution(void de.scrum_master.app.Application.main(String[]))
    execution(void de.scrum_master.app.Application.say(String))
    Hello world!