Search code examples
aopaspectjspring-aopload-time-weaving

What does spring-instrument.jar do that aspectj-weaver.jar does not?


I'm trying to configure my Spring Boot application to use AspectJ load-time weaving. Using byte-buddy agent to hot-attatch the aspectj-weaver.jar seems to be working fine for both Spring beans and non-Spring classes (e.g. MyBatis TypeHandlers). However I also see a lot of recommendations, including the Spring doc, on attaching spring-instruments.jar and using the @EnableLoadTimeWeaving annotation.

  1. What exactly does the spring-instruments.jar do that aspectj-weaver.jar does not? In my experience, even for Spring beans, spring-instruments.jar agent does not seem to be always sufficient to enable LTW, and aspectj-weaver.jar agent still needs to be available, otherwise (sometimes) there are errors around not being able to find the aspectOf method.
  2. If both spring-instruments.jar (with @EnableLoadTimeWeaving) and aspectj-weaver.jar are attatched, will Spring beans be woven twice?

Solution

    1. It does something similar to what you are doing with byte-buddy-agent, i.e. hot-attach aspectjweaver. I.e., you are basically re-inventing the wheel. The downside to hot-attaching is that it is too late to weave some classes and classloaders already active before hot-attachment takes place. The better alternative is to use javaagent:/path/to/aspectjweaver.jar, because then attachment occurs as early as possible.

    2. No, nothing will be woven twice.

    Now, if you absolutely wish to avoid -javaagent:... but are using an executable (Spring Boot) JAR, I have a goodie for you. Quoting from other answers I wrote in similar contexts here:


    If you are running your applications as executable JARs on JRE 9+ (Spring Boot ones or other types), probably Agent Embedder Maven Plugin is what you want.

    It enables you to embed a java agent in your executable JAR and have it started automatically using the Launcher-Agent-Class JVM mechanism.

    Unique features added by this plugin and unavailable via the original JVM mechanism: You can

    • embed and run multiple agents (the JVM supports only one out of the box),
    • pass an option string to each agent, just like from the JVM command line.

    Spoiler: I am the author of the plugin and also happen to be the current maintainer of AspectJ.

    P.S.: In the case of the AspectJ weaver, as the JVM starts the agent very early, weaving will be active without extra Spring configuration and it should work for all classloaders - no more ClassLoader [...] does NOT provide an 'addTransformer(ClassFileTransformer)' method errors as seen when hot-attaching the weaver via spring-instrument.jar.