2

I have a Spring project managed by Maven. Instead of using execution pointcut designator like the following:

@Before("execution(* my.app.TestUtil.myStaticClass(..))")
public void logBeforeTestUtil(JoinPoint joinPoint) {
    System.out.println("*** hijacked : " + joinPoint.getSignature().getName());
}

I want to use call pointcut designator like:

@Before("call(* my.app.TestUtil.myStaticClass(..))")
public void logBeforeTestUtil(JoinPoint joinPoint) {
    System.out.println("*** hijacked : " + joinPoint.getSignature().getName());
}

However, my IDE (IntelliJ) tells me call pointcut designator isn't supported by Spring, even after I removed spring-aop in the pom.xml.

I'd like to mention the example above with execution pointcut designator is working and Spring AOP does not supports all AspectJ pointcut designators.

This answer shows how to use Load Time Weaving without using Spring. I am wondering if we can use Spring + AspectJ without Spring AOP. If so, how to do it?

EDIT: add pom.xml and context configuration files

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>my.app</groupId>
    <artifactId>myapp</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <properties>
        <spring.version>4.3.4.RELEASE</spring.version>
        <jackson.version>2.7.3</jackson.version>
        <aspectj.version>1.8.4</aspectj.version>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <aspectj.version>1.8.4</aspectj.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!--<dependency>-->
            <!--<groupId>org.springframework</groupId>-->
            <!--<artifactId>spring-aop</artifactId>-->
            <!--<version>${spring.version}</version>-->
        <!--</dependency>-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-instrument</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>${aspectj.version}</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>${aspectj.version}</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>${jackson.version}</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
    </dependencies>
</project>

application-context.xml

package my.app;

import org.springframework.context.annotation.*;

@Configuration
@EnableLoadTimeWeaving(aspectjWeaving = EnableLoadTimeWeaving.AspectJWeaving.ENABLED)
public class AppConfig {
}

META-INF/aop.xml

<!DOCTYPE aspectj PUBLIC "-//AspectJ//DTD//EN" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd">
<aspectj>
    <weaver>
        <include within="my.app.utils.*"/>
        <include within="my.app.aspect.*"/>
    </weaver>
    <aspects>
        <aspect name="my.app.aspect.LoggingAspect" />
    </aspects>
</aspectj>
Community
  • 1
  • 1
Kwadz
  • 2,206
  • 2
  • 24
  • 45
  • With, as mentioned in your link, load time weaving which is plain aspectJ. Or resort to compile time weaving. – M. Deinum Jun 21 '17 at 13:22
  • I am using LTW to intercept static methods. If my LTW, which is plain AspectJ, is working with `execution` how come it does not work with `call`? – Kwadz Jun 21 '17 at 13:35
  • 1
    The fact that you get that warning doesn't mean it doesn't work. (I suspect IntelliJ triggers this message only on the plain fact of the Spring Facet and AspectJ combo). – M. Deinum Jun 21 '17 at 13:43
  • Sorry, may be I should have mentioned nothing is intercepted while using `call`. If I replace `execution` by `call`, the interception is no longer working. – Kwadz Jun 21 '17 at 14:16
  • @Kwadz could you please post pom.xml and context configuration? – Taras Velykyy Jun 23 '17 at 12:10
  • @tvelykyy I added the content of the desired files. – Kwadz Jun 25 '17 at 16:13
  • @M.Deinum Do you understand why the interception is working with `execution` while it is not with `call`? – Kwadz Jun 27 '17 at 15:21
  • In which case. With default spring AOP yes, with load and compile time weaving it should work. – M. Deinum Jun 27 '17 at 17:33
  • My example is Load Time Weaving. It should work but unfortunately it's not the case. It works only with `execution`. If I replace `execution` by `call` nothing is intercepted anymore. – Kwadz Jun 27 '17 at 19:17
  • 1
    For `execution` the **called** code must be advised. For `call` the **calling** code must be advised. Is the **calling** code within the scope of `my.app.utils.*` or `my.app.aspect.*`? Those are the only packages you configured your weaver to include. If the caller is from org.springframework... it will not be advised. – sheltem Jun 28 '17 at 12:18
  • 1
    @sheltem You're right. The **calling** code is in `my.app.app.App` which was not configured in `META-INF/aop.xml`. I just added it and now the interception is working even with `call`. Well done! Feel free to put your comment as an answer, I'll accept it. – Kwadz Jun 28 '17 at 13:30

1 Answers1

2

For execution the called code must be advised. For call the calling code must be advised. Is the calling code within the scope of my.app.utils.* or my.app.aspect.*? Those are the only packages you configured your weaver to include. If the caller is from org.springframework... or other parts of your application, it will not be advised.

Converted to answer from previous comment.

sheltem
  • 3,754
  • 1
  • 34
  • 39