Search code examples
javaspringaspectjaspectj-maven-plugin

AspectJ not working with compile time weaving


I'm trying to do a SQL query profiling using AOP

Below is my snippet from @Aspect defenition

@Pointcut("(call(* org.springframework.jdbc.core.JdbcTemplate.query*(..)) || call(* org.springframework.jdbc.core.JdbcTemplate.update*(..)))")
public void profileQuery() {
}

@Around("profileQuery()")
public Object profile(ProceedingJoinPoint thisJoinPoint) throws Throwable {
    logger.info("profileQuery() aspect Before");
    Object pjp= thisJoinPoint.proceed();
    logger.info("profileQuery() aspect After");
    return pjp;
}

POM snippet for aspectj maven plugin

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>aspectj-maven-plugin</artifactId>
    <version>1.14.0</version>
    <configuration>
        <complianceLevel>${java.version}</complianceLevel>
        <showWeaveInfo>true</showWeaveInfo>
        <verbose>true</verbose>
        <Xlint>ignore</Xlint>
        <encoding>UTF-8 </encoding>
    </configuration>
    <dependencies>
    </dependencies> 
    <executions>
        <execution>
            <id>compile</id>
            <phase>process-classes</phase>
            <goals>
                <goal>compile</goal>
                <goal>test-compile</goal>
            </goals>    
        </execution>
    </executions>
</plugin>

POM snippet for maven compiler plugin

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
        <fork>true</fork>
        <source>${java.version}</source>
        <target>${java.version}</target>
        <useIncrementalCompilation>false</useIncrementalCompilation>
        <excludes>
          <exclude>**/*.*</exclude>
        </excludes>
    </configuration>
</plugin>

I tried using Eclipse and also tried compiling outside Eclipse Command used mvn clean install -Dmaven.test.skip=true

No issues in building and deploying it on Tomcat 8.5.83 , also the APIs are working, but the aspect is not being intercepted as expected.


Solution

  • There are several problems in your POM and code, which I fixed in this pull request, for example:

    • You configured AspectJ Maven Plugin in the pluginManagement section, but forgot to actually add the plugin to the project in a separate plugins section.

    • Your example does not contain a test base directory. Therefore, you need to remove goal test-compile in order to avoid build errors.

    • When using org.codehaus.mojo:aspectj-maven-plugin, using complianceLevel is not enough, you also need to specify source and target. Or you simply switch to the better dev.aspectj:aspectj-maven-plugin variant, then complianceLevel is enough.

    • Package name aspect is not OK for native AspectJ, because in AspectJ it is a reserved keyword. So I renamed your package to aop.

    • Your pointcut call(* service.apiInnerService(..)) is wrong, you forgot the class name and should use call(* service.MainService.apiInnerService(..)) instead.

    • A native AspectJ aspect should not have a @Component annotation, because that is used for Spring AOP proxy-based aspects. You should avoid Spring to pick it up a second time.

    In addition to these changes, I also removed some cruft from your code, reformatted everything a bit and added a main method to AppConfig, so I could easily run the applicaion from my IDE and verify that the aspect works. But it should work the same in your WAR.

    When running the application, now I see:

    Before Around :testAspectPointcut
    Innerservice
    After Around
    Success
    

    I.e., the aspect is working, intercepting your private method call. But allow me to say that if you need to apply aspects to private methods, you most likely have a design problem in your application.