Search code examples
javascalasbtaspectjsbt-assembly

aspectjweaver/javaagent in a sbt-assembly fatjar


I have a library that requires me to specify a javaagent using the aspectjweaver jar. eg.

java -jar  -javaagent:/some/location/aspectjweaver-1.8.2.jar myFatJar.jar

This works fine. However, the environment that my fatjar will be running on does not have aspectjweaver-1.8.2.jar and I can't put it there (getting a more configurable environment may be a route I go down later).

Is there a way, preferably using sbt-assembly, to package up aspectjweaver into my fatjar, and run it that way? If it matters, my application is a Spray one using Scala, built using sbt.

Constraints

  • Can't have a separate jar
  • Can specify an arbitrary java command
  • Have complete control of the build process

Solution

  • If you have, as you say, complete control over the build process, why don't you use compile-time weaving instead of load-time weaving? Then you just package the AspectJ runtime library aspectjrt.jar into your fat jar and are done with the problem. You even avoid the overhead of runtime weaving on application start-up.

    The only reason I can think of which makes this approach problematic is that you need to weave joinpoints outside the control of your build process.


    Update 2024-03-19: 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.