0

I am trying to intercept any method in my application which is annotated with my custom developed annotation.

Initially I used the Spring AOP which works fine. But, it is not intercepting if the method call is in the same target class. Going through the official docs, I got to know that the Spring AOP uses proxy beans for the same.

One workaround I found was to self inject the target class. But, this seems like too much fuss. Like every time I am adding my custom annotation to a method, I need to make sure that I add the @Scope annotation, set the proxyMode & self inject target class as shown here

Later I moved on to configuring and using native AspectJ.

This is my Custom annotation:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TrackTime {
    String description() default "";
}

Here is the Aspect for TrackTime annotation:

@Configuration
@Slf4j
@Aspect
public class TrackTimeServiceImpl {

    @Pointcut("execution(public * *(..))")
    public void methodsToBeProfiled(){

    }

    @Around("methodsToBeProfiled() && @annotation(x.y.z.TrackTime)")
    public Object audit(ProceedingJoinPoint joinPoint) throws Exception {
        //Business logic
    }
}

I would like to mention here that my application is running on Jetty server.

The configuration file:

@Configuration
@EnableLoadTimeWeaving(aspectjWeaving = EnableLoadTimeWeaving.AspectJWeaving.ENABLED)
@EnableSpringConfigured
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class TrackTimeConfig implements LoadTimeWeavingConfigurer {

    @Override
    public LoadTimeWeaver getLoadTimeWeaver() {
        return new InstrumentationLoadTimeWeaver();
    }

}

The aop.xml file: Path to file: /resources/META-INF/aop.xml

<!DOCTYPE aspectj PUBLIC "-//AspectJ//DTD//EN" "https://www.eclipse.org/aspectj/dtd/aspectj.dtd">
<aspectj>

    <weaver>
        <!-- only weave classes in our application-specific packages -->
        <include within="in.xxx.*"/>
    </weaver>

    <aspects>
        <!-- weave in just this aspect -->
        <aspect name="in.xxx.yyy.zzz.TrackTimeServiceImpl"/>
    </aspects>

</aspectj>

Relative dependencies added in parent pom.xml have been mentioned here:

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.13</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>5.3.21</version>
        </dependency>

My service class:

@Component
public class SomeService {

    public void a(){
        b();
    }

    @TrackTime
    public void b(){
        //business logic
    }
}

Now when the method a() is called from the controller, even though the b() has the @TrackTime annotation, it is not intercepted.

Also, I would like to mention that I have set the following program arguments while running the application

-javaagent:/Users/xxx/.m2/repository/org/springframework/spring-instrument/5.3.6/spring-instrument-5.3.6.jar
-javaagent:/Users/xxx/.m2/repository/org/aspectj/aspectjweaver/1.9.6/aspectjweaver-1.9.6.jar

I have gone through docs, articles, followed solutions on stackoverflow. But, for the above mentioned configuration/code, it is not working as I want.

Requesting help from the community.

Thanks in advance.

2 Answers2

3

I did not try to run your example locally yet, but noticed two details at first glance in your code:

  1. You are configuring both @EnableLoadTimeWeaving (for native AspectJ) and @EnableAspectJAutoProxy (for Spring AOP), which might be conflicting with each other. Try to remove the latter and see if it fixes the problem.

  2. In aop.xml, you are using <include within="in.xxx.*"/>. Please note that this will only include classes directly in the in.xxx package, but not classes in sub-packages. In order to include them as well, please use the double-dot notation in.xxx..*.

Feel free to report back if it is still not working with the suggested changes. I can take a closer look then.

dreamcrash
  • 47,137
  • 25
  • 94
  • 117
kriegaex
  • 63,017
  • 15
  • 111
  • 202
  • Hi kriegaex, I have removed the `@EnableAspectJAutoProxy` as suggested. But, when I changed from `in.xxx.*` to `in.xxx..*` in aop.xml, I am getting the following error on all classes where I have used my custom annotation. `org.aspectj.weaver.BCException: Unable to find Asm for stackmap generation (Looking for 'aj.org.objectweb.asm.ClassReader'). Stackmap generation for woven code is required to avoid verify errors on a Java 1.7 or higher runtime when weaving type in.xxx.y.z when weaving classes when weaving ` – Karthik S Jhingade Jun 27 '22 at 05:28
  • Which Java version do you use for compilation? I see that your AspectJ Weaver is 1.8.13 in the Maven POM, 1.9.6 on your `-javaagent` command line, but then you use a brandnew Spring Aspects 5.3.21 in combination with Spring Instrument 5.3.6. Maybe you want to harmonise those versions and use 5.3.21 for all `org.springframework` stuff and the latest 1.9.9.1 for all `org.aspectj` stuff, especially if you compile to a byte code to a more recent Java version. A full [MCVE](https://stackoverflow.com/help/mcve) on GitHub would be much better than just fragmentary snippets. – kriegaex Jun 27 '22 at 17:02
  • Hi kriegaex, I am using java 11 and yes, the versions don't match for the AspectJ Weaver as you mentioned. After some tweeks, trial and error method, I was finally able to intercept nested methods and configure native AspectJ properly. I would be posting the solution here in sometime. – Karthik S Jhingade Jun 28 '22 at 15:23
0

First of all, I would like to thank @hfontanez, @void void & @kriegaex for responding and helping me out in moving forward in solving the problem statement.

So if anyone is looking out on how to intercept nested & private methods, let's have this as a one stop in configuring native AspectJ.

Please check my POC here on github for a working example.

In my case, I added the aspectjweaver JAR in my project structure and passed the arguments through VM Options in IDE.

That all !! Nested/Private methods will now be intercepted.

Thank you, Karthik

  • I tried pulling this project down and running it, but it was NOT getting into the private method. Did something change? – Dan Dec 14 '22 at 06:20